Проблема Aggregate/Annotate с OuterRef не работает с отношениями без FK в Django? Требуется ли FK?
У меня проблема с парой моделей из разных "общих приложений", которые у меня есть. Я не могу соединить их вместе, потому что эти приложения существуют в нескольких проектах (некоторые друг без друга), поэтому это нарушит другие проекты.
Это неуправляемая модель из appA
- которая использует другую базу данных, которую мы будем называть databaseA
для этого примера; в идеальном мире 'location_id' был бы FK, но, как я описал выше, это невозможно.
class Enrollment(models.Model):
id = models.IntegerField(db_column="ID", primary_key=True)
location_id = models.IntegerField(db_column="locationID")
grade = models.CharField(db_column="grade", max_length=10)
student_count = models.IntegerField(db_column="studentCount")
class Meta(object):
managed = False
db_table = "mytable_Enrollments"
Это управляемая модель из appB
, которая использует databaseB
(которая является основной базой данных, используемой остальными приложениями в этом проекте); 'pk' или 'id' этой модели - это то, что указано в модели Enrollment
в разделе location_id
class Location(models.Model):
name = models.CharField(max_length=50)
alternate_name = models.IntegerField()
Если я хочу получить Enrollment
объекты для Location
, я должен явно подставить число для идентификатора, как например:
location = Location.objects.get(id=1)
enrollments = Enrollment.objects.filter(location_id = location.id)
Но я пытаюсь аннотировать 'total_student_count' на модель Location
следующим образом:
enrollments = (
Enrollment.objects.filter(location_id=OuterRef("pk"))
.order_by()
.values("location_id")
)
total_enrollments = enrollments.annotate(
total_student_count=Sum("student_count")
).values("total_student_count")
locations = (
Location.objects.all()
.order_by()
.annotate(
total_enrollments=Subquery(total_enrollments),
)
)
Я сделал это аналогично примерам из документации .
Однако это просто возвращает total_enrollments: None
в Queryset.
Если я заменяю OuterRef("pk")
на целое число, например, 1 или 2 - переменная enrollments
возвращает мне то, что я ожидал. Но использование OuterRef
, кажется, ломается - и я не уверен почему.
Должен ли он быть FK? Из всего, что я нашел в Интернете, это не обязательно. Но я никак не могу найти способ заставить это работать.
У кого-нибудь есть идеи?
Вы можете попробовать что-то вроде следующего запроса
from django.db.models import Sum, F, Window
results = Enrollment.objects.filter(
location_id__in=[location_ids]
).values(
'location_id'
).distinct().annotate(
total_student_count=Window(
expression=Sum("student_count"), partition_by=[F("location_id")],
)
).order_by('total_student_count')
Это отфильтрует зачисленных на основе предоставленных идентификаторов местоположения и даст общее количество зачисленных на основе каждого идентификатора местоположения