#36197 closed Bug (fixed)
Model.relatedmanager.count() always 0 for custom ManyToMany relationships with through model with to_fields
Reported by: | mfontana-elem | Owned by: | Simon Charette |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 5.1 |
Severity: | Release blocker | Keywords: | |
Cc: | ontowhee, Simon Charette, Mariusz Felisiak | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
While upgrading my codebase to Django 5.1 I started noticing some tests were failing. At the end of the day, the reason was that, given an object's manager for a ManyToMany
relation I was getting object.relatedmanager.count() != len(object.relatedmanager.all())
. The LHS was always zero.
To illustrate my setup, I have the following models:
from django.db import models class Course(models.Model): uuid = models.UUIDField(unique=True, editable=False, verbose_name="UUID") title = models.CharField(max_length=200) class Student(models.Model): uuid = models.UUIDField(unique=True, editable=False, verbose_name="UUID") name = models.CharField(max_length=100) courses = models.ManyToManyField(Course, through="CourseStudent", related_name='students') class CourseStudent(models.Model): course = models.ForeignKey(Course, to_field="uuid", on_delete=models.RESTRICT, null=False) student = models.ForeignKey(Student, to_field="uuid", on_delete=models.RESTRICT, null=False)
And the problem is that it course.students.count()
generates the following SQL (both for SQLite and Postgres):
SELECT COUNT(*) AS "__count" FROM "courses_coursestudent" WHERE "courses_coursestudent"."course_id" = '00000000000000000000000000000001'
,
which is of course wrong.
Under the exact same setup, Django 5.0 generates:
SELECT COUNT(*) AS "__count" FROM "courses_student" INNER JOIN "courses_coursestudent" ON ("courses_student"."uuid" = "courses_coursestudent"."student_id") WHERE "courses_coursestudent"."course_id" = '0817704cdf2d478dba5d629b8997f73b'
.
I attach a .zip
containing a Dockerfile
and a src
directory to easily reproduce this behavior.
Best regards,
Attachments (1)
Change History (9)
by , 3 days ago
Attachment: | count-bug.zip added |
---|
comment:1 by , 3 days ago
Summary: | `Model.relatedmanager.count()` fails for custom ManyToMany relationships which don't use `id` → `Model.relatedmanager.count()` fails for custom ManyToMany relationships with `through` definition |
---|
comment:2 by , 3 days ago
Cc: | added |
---|---|
Severity: | Normal → Release blocker |
Summary: | `Model.relatedmanager.count()` fails for custom ManyToMany relationships with `through` definition → Model.relatedmanager.count() always 0 for custom ManyToMany relationships with through model with to_fields |
Triage Stage: | Unreviewed → Accepted |
comment:3 by , 3 days ago
Owner: | set to |
---|---|
Status: | new → assigned |
I can work on that one.
We can't be systematically using self.instance.pk
here
comment:4 by , 3 days ago
Has patch: | set |
---|
comment:5 by , 2 days ago
Triage Stage: | Accepted → Ready for checkin |
---|
Thank you! Replicated and bisected to 66e47ac69a7e71cf32eee312d05668d8f1ba24bb (#29725)
Possible regression test/asserts
tests/m2m_through/tests.py