Using the accepted answer in Class-based views for M2M relationship with intermediate model, I am able to save the Membership
if I hard code an ID for its foreignkey to Group
, despite not having any information for date_joined
and invite_reason
, but the Group
for which the form is filled out never gets saved, and therefore I cannot supply Membership
with the correct ID. In fact, any time I try to save thegroup
, before or after the code in the accepted answer, I get the same AttributeError
as the OP:
Cannot set values on a ManyToManyField which specifies an intermediary model. Use Membership's Manager instead.
Is there a way to make this code actually work? Am I being led astray? What would be the proper way to save something with a many-to-many field that goes through a mapping table? The answers I've found have confused me more than helped me.
For reference, should the question ever be deleted:
models.py
class Person(models.Model):
name = models.CharField(max_length=128)
def __unicode__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __unicode__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
Accepted Answer (With an additional line to hard code an ID)
from django.views.generic.edit import ModelFormMixin
from django.views.generic import CreateView
class GroupCreate(CreateView):
model = Group
def form_valid(self, form):
self.object = form.save(commit=False)
for person in form.cleaned_data['members']:
membership = Membership()
membership.group = self.object
membership.group_id = 108 # Added line
membership.person = person
membership.save()
return super(ModelFormMixin, self).form_valid(form)
Note: I had to add the id line because I would get the following IntegrityError
without it:
Column 'group_id' cannot be null
In case it's pertinent, I am trying to save this to a MySQL database.