[Django] #36197: `Model.relatedmanager.count()` fails for custom ManyToMany relationships which don't use `id`

5 views
Skip to first unread message

Django

unread,
Feb 17, 2025, 5:38:37 AM2/17/25
to django-...@googlegroups.com
#36197: `Model.relatedmanager.count()` fails for custom ManyToMany relationships
which don't use `id`
-------------------------------------+-------------------------------------
Reporter: mfontana-elem | Type: Bug
Status: new | Component: Database
| layer (models, ORM)
Version: 5.1 | Severity: Normal
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
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,
--
Ticket URL: <https://code.djangoproject.com/ticket/36197>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Feb 17, 2025, 5:39:02 AM2/17/25
to django-...@googlegroups.com
#36197: `Model.relatedmanager.count()` fails for custom ManyToMany relationships
which don't use `id`
-------------------------------------+-------------------------------------
Reporter: mfontana-elem | Owner: (none)
Type: Bug | Status: new
Component: Database layer | Version: 5.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by mfontana-elem):

* Attachment "count-bug.zip" added.
Reply all
Reply to author
Forward
0 new messages