Je suis en train de développer un système d’invitation et je me suis retrouvé devant un problème que je souhaitais résoudre le plus élégamment possible. Ai-je réussis ? À vous de me le dire 😉
L’explication en commentaire dans le code ci-dessous. Le code à été réduit au minimum pour se concentrer sur la partie Form
# Model class Organisation(models.Model): name = models.CharField(max_length=255) class Invite(models.Model): organisation = models.ForeignKey(Organisation) email = models.EmailField() # Form class InviteForm(ModelForm): def __init__(self, *args, **kwargs): # On passe la foreign_key en paramètre à partir de la view if kwargs.has_key('organisation'): self.organisation = kwargs.pop('organisation') super(InviteForm, self).__init__(*args, **kwargs) def save(self, commit=True): # On sauve sans faire la requête SQL (commit=False) pour # pouvoir ajouter à l'instance l'organisation super(InviteForm, self).save(commit=False) # On ajoute à l'instance la foreign_key self.instance.organisation = self.organisation # On peut maintenant sauver super(InviteForm, self).save(commit) class Meta: model = model.Invite fields = ['email'] # View def invite_add(request, oid): organisation = models.Organisation.objects.get(pk=oid) if request.method == 'POST': # Dans la vue j'envoie la foreign_key form = forms.InviteForm(request.POST, organisation=organisation) if form.is_valid(): form.save()
Pourquoi cela me parait élégant (ou du moins pas trop dégeulasse):
- La logique reste dans le Form (et pas dans la view comme j’ai pus le voir sur internet)
- On n’altère pas le fonctionnement de save(). Le paramètre commit reste fonctionnel
Je n’ai pas trouvé d’autres solutions élégante pour faire cela, si vous en avez une je la prends avec plaisir ;).
Solution élégante.
Merci 🙂