#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.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/django-updates/01070195137cf761-193f3bbe-bd6d-4395-b123-9c6cbd8cabb0-000000%40eu-central-1.amazonses.com.

Reply via email to