OuterRef的汇总/注释问题在Django中不使用非FK关系?需要FK吗?

发布于 2025-02-01 20:30:03 字数 2030 浏览 1 评论 0原文

我有一些来自不同“共享应用程序”的模型的问题。我无法将它们放在一起,因为这些应用程序存在于多个项目(有些没有彼此)中,因此它将破坏其他项目。

这是一个来自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”是注册location_id下的模型中列出的内容,

class Location(models.Model):
    name = models.CharField(max_length=50)
    alternate_name = models.IntegerField()

如果我想获得注册一个位置,我必须明确地为ID上的数字放入一个数字:

location = Location.objects.get(id=1)
enrollments = Enrollment.objects.filter(location_id = location.id)

但是我正在尝试将'total_student_count'注释到location> 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),
    )
)

上是否类似于 from文档中的示例

但是,这只是返回total_enrollments:querySet中的无

如果我将OuterRef(“ PK”)替换为1或2(例如1或2)的整数 - 注册变量使我回到了我期望的东西。但是使用outerRef似乎破裂了 - 我不确定为什么。

是否需要成为FK?从我在网上找到的所有内容中,它不需要。但是我似乎找不到做这项工作的方法。

有人有什么想法吗?

I've got an issue with a couple models from different 'shared apps' that I have. I can't FK them together, because these apps exist in multiple projects (some without each other) so it would break other projects.

This is an unmanaged model from appA - which uses a different database which we will call databaseA for this example; in a perfect world 'location_id' would be the FK but as I've described above, it cannot be.

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"

This is a managed model from appB which uses databaseB (which is the primary database used by the rest of the apps in this project); the 'pk' or 'id' of this model is what is listed in the Enrollment model under location_id

class Location(models.Model):
    name = models.CharField(max_length=50)
    alternate_name = models.IntegerField()

If I want to get Enrollment objects for a Location, I have to explicitly put a number in for the id like so:

location = Location.objects.get(id=1)
enrollments = Enrollment.objects.filter(location_id = location.id)

But I'm trying to annotate the 'total_student_count' onto the Location model like so:

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),
    )
)

I did this similar to examples from the documentation.

However this just returns total_enrollments: None in the Queryset.

If I replace OuterRef("pk") with an integer like 1 or 2 - the enrollments variable gives me back what I would expect. But using the OuterRef seems to break - and I'm not sure why.

Does it need to be a FK? From everything I've found online, it doesn't need to be. But I can't seem to find a way to make this work.

Anyone have any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

源来凯始玺欢你 2025-02-08 20:30:03

您可以尝试以下查询之类的东西,

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')

这将根据提供的位置ID过滤注册,并根据每个位置ID提供总注册。

You can try something like following query

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')

This will filter the Enrollements based on provided location ids and will give total enrollements based on each location id

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文