views:

27

answers:

2

I have Publications and Authors. Since the ordering of Authors matters (the professor doesn't want to be listed after the intern that contributed some trivial data), I defined a custom many-to-many model:

class Authorship(models.Model):
    author = models.ForeignKey("Author")
    publication = models.ForeignKey("Publication")
    ordering = models.IntegerField(default=0)

class Author(models.Model):
    name = models.CharField(max_length=100)

class Publication(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author, through=Authorship)

I've got aModelForm for publications and use it in a view. Problem is, when I call form.save(), the authors are obviously added with the default ordering of 0. I've written a OrderedModelMultipleChoiceField with a clean method that returns the objects to be saved in the correct order, but I didn't find the hook where the m2m data is actually saved, so that I could add/edit/remove the Authorship instances myself.

Any ideas?

+1  A: 

I'm not sure if there's a hook for this, but you could save it manually with something like:

form = PublicationForm(...)
pub = form.save(commit=False)
pub.save()
form.save_m2m()

So you can handle any custom actions in between as required. See the examples in the docs for the save method.

ars
+1  A: 

If you are using a custom M2M table using the through parameter, I believe you must do the saves manually in order to save the additional fields. So in your view you would add:

...
publication = form.save()
#assuming that these records are in order! They may not be
order_idx = 0
for author in request.POST.getlist('authors'): 
    authorship = Authorship(author=author, publication=publication, ordering=order_idx)
    authorship.save()
    order_idx += 1

You may also be able to place this in your ModelForm's save function.

Jordan Reiter
You're right, of course. Thanks!
piquadrat