ModelForm et ForeignKey
29 novembre 2014
Aymeric
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.
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()
Bien que je n'en soit pas entièrement satisfait, cette solution solution me convient pour plusieurs raisons:
- 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 ;).