Search code examples
pythondjangodjango-modelsmany-to-manym2m

m2m relations are not displayed or saved in django


class A(Model):
    to_b = ManyToManyField('B', blank=True, through='AtoB')

class B(Model):
    to_a = ManyToManyField('A', blank=True, through='AtoB')

class AtoB(Model):
    a =  ForeignKey('A', on_delete=CASCADE)
    b =  ForeignKey('B', on_delete=CASCADE)
    usr =  ForeignKey(settings.USER, on_delete=CASCADE)
    # some other fields

Im making a django application.
This is roughly equivalent to what i have in my models.py
I need m2m relation between A and B to go through another model because i need to store additional data there.
Now there is a problem - when i try to save instance of model A in my custom view, relations with B instances are not saved no matter whether i pick them or not. And when i go to http://127.0.0.1:8000/admin and try to create instance of A from there, i dont even see proper field (should be <select multiple> i guess) for selecting relations with B.
Can someone please explain me why relations are not saved, and not even displayed in /admin?
Here is code roughly equivalent to what i have in views.py:

class Create(CreateView):
    model = None  # A or B
    template_name = 'something.html'

    def form_valid(self, form):
        self.object = form.save(commit=False)
        form.save()
        return HttpResponseRedirect(self.get_success_url())

in urls.py i specify additional arguments like this: views.Create.as_view(model=models.A, fields=['to_b'])


Solution

  • It is not going to work. If you are using your own ManytoMany intermediary table, you have to manually manage and save the objects yourself. Using Django's builtin functions won't work.

    Save Object A, then save Object B and then save the relation in your AtoB table (which is also an object).

    a_to_b = AtoB.objects.create(a=object_a, b=object_b, user=self.request.user)
    print(a_to_b)
    

    [...] Note that if you are using an intermediate model for a many-to-many relationship, some of the related manager’s methods are disabled, so some of these examples won’t work with such models.

    https://docs.djangoproject.com/en/1.10/topics/db/examples/many_to_many/

    Your error is explained here: https://docs.djangoproject.com/en/1.10/topics/db/models/#intermediary-manytomany