2010-10-26 6 views
3

J'ai Publication s et Author s. Depuis l'ordre des questions de Author (le professeur ne veut pas figurer après le stagiaire qui a contribué des données triviales), je défini un modèle sur mesure many-to-many:Django: enregistrer un ModelForm avec des modèles personnalisés plusieurs-à-plusieurs

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) 

J'ai obtenu un ModelForm pour les publications et l'utiliser dans une vue. Le problème est, quand j'appelle form.save(), les auteurs sont évidemment ajoutés avec la commande par défaut de 0. J'ai écrit un OrderedModelMultipleChoiceField avec une méthode clean qui retourne les objets à enregistrer dans le bon ordre, mais je n'ai pas trouvé le crochet où les données m2m sont réellement enregistrées, de sorte que je pourrais ajouter/modifier/supprimer les instances Authorship moi même.

Des idées?

Répondre

2

Si vous utilisez une table M2M personnalisée à l'aide du paramètre through, je crois que vous devez effectuer les sauvegardes manuellement afin de sauvegarder les champs supplémentaires. Donc, selon vous, vous ajoutez:

... 
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 

Vous pourriez également être en mesure de placer dans votre fonction de ModelForm save.

+0

Vous avez raison, bien sûr. Merci! –

1

Je ne sais pas s'il y a un crochet pour cela, mais vous pouvez l'enregistrer manuellement avec quelque chose comme:

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

Vous pouvez donc gérer toutes les actions personnalisées entre au besoin. Voir les exemples dans les documents pour le save method.

Questions connexes