I'm having trouble in saving a m2m data, containing a 'through' class table. I want to save all selected members (selected in the form) in the through table. But i don't know how to initialise the 'through' table in the view.
my code:
class Classroom(models.Model):
user = models.ForeignKey(User, related_name = 'classroom_creator')
classname = models.CharField(max_length=140, unique = True)
date = models.DateTimeField(auto_now=True)
open_class = models.BooleanField(default=True)
members = models.ManyToManyField(User,related_name="list of invited members", through = 'Membership')
class Membership(models.Model):
accept = models.BooleanField(User)
date = models.DateTimeField(auto_now = True)
classroom = models.ForeignKey(Classroom, related_name = 'classroom_membership')
member = models.ForeignKey(User, related_name = 'user_membership')
and in the view:
def save_classroom(request):
classroom_instance = Classroom()
if request.method == 'POST':
form = ClassroomForm(request.POST, request.FILES, user = request.user)
if form.is_valid():
new_obj = form.save(commit=False)
new_obj.user = request.user
new_obj.save()
membership = Membership(member = HERE SELECTED ITEMS FROM FORM,classroom=new_obj)
membership.save()
How should I initialise the membership for the Membership table to be populated right?
This is how I did it in a generic UpdateForm class-based view (django 1.8) for a similar yet different application using the form_valid method.
Like what dzida did, but use form.cleaned_data instead of request.post:
You also need to consider some memberships might be deleted, so:
If you use model forms (like in a generic CBV:
form_class=ClassroomForm
), override and put the saving logic above in thesave
method, something like:In case of using normal m2m relation (not through intermediary table) you could replace:
with
But in case of using intermediary tables you need to manually handle POST data and create Membership objects with all required fields (similar problem). The most basic solution is to change your view to something like:
Note how request.POST is manipulated (.getlist). This is because post and get are QueryDict objects which has some implications (request.POST['members'] will return always one object!).
You can modify this code to get it more reliable (error handling etc.), and more verbose, eg:
But note that you are performing some db queries in a loop which is not a good idea in general (in terms of performance).
You also need to specify the classroom for the membership:
I guess you should also remove
User
inaccept = models.BooleanField(User)
. It shouldn't be necessary to set the date upon saving if you are usingauto_now
! But maybe `auto_now_add is more likely what you need (http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.DateField)