【问题标题】:Get a django queryset that includes data from 5 linked models获取包含来自 5 个链接模型的数据的 django 查询集
【发布时间】:2020-05-27 18:01:20
【问题描述】:

我有 5 个模型与这样的外键链接:

Section (Registration.section)
^ 1
|
v ∞
Registration < ∞ --- 1 > Event (Registration.event)
^ ∞
|
v 1
User (Registration.user, Profile.user)
^ 1
|
v 1
Profile

从这些链接模型中,我尝试在这样的表中显示数据:

| ID             | Other Profile fields    | Section1                     | Section2                    | SectionN |
|----------------|-------------------------|------------------------------|-----------------------------|----------|
| user1.username | eg. user1.profile.grade | Registration.objects.get(    | Registration.objects.get(   |
                                           |    section=Section1,         |   section=Section1,         |
                                           |    user=user1   |   user=user1   |
                                           | ).event                      | ).event                     |
|----------------|-------------------------|------------------------------|-----------------------------|----------|
| user2.username | user2.profile.grade     | ...event                     |None (needs to handle this)  | 
|----------------|-------------------------|------------------------------|-----------------------------|----------|
| user3.username | user3.profile.grade     | None (needs to handle this)  |None (needs to handle this)  |          |

每个用户都有不同的行。我无法弄清楚如何有效地做的是获得每个部分的注册。

我可以通过在 python 中使用字典和循环等手动操作数据来做到这一点,但这非常低效,如果用户列表太大,我的服务器在完成该过程之前就会超时。

我需要创建什么查询集结构才能在模板中输出这样的数据?

每个部分的每个用户只有一个注册对象:

class Registration(models.Model):

    event = models.ForeignKey(Event, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    section = models.ForeignKey(section, on_delete=models.CASCADE)

    class Meta:
        unique_together = ("event", "user", "section")

【问题讨论】:

    标签: python django django-queryset


    【解决方案1】:

    在实践中,我建议你做分页:

    1. 仅查询前 100 个用户 -> 您有一个用户 ID 列表。
    2. Registration.objects.filter(user__in=[1,42,...]).values_list()
    3. 将数据配对(它甚至可能以正确的顺序从数据库中出来)。
    4. 对其他相关模型执行此操作。

    这应该很快。无论如何,您都不想在一个页面上看到超过 100 个用户。

    回答您的问题:

    您可以尝试使用 values_list,如果您使用 Registration.objects.values_list('event__property', 'user__username', 'user__profile__grade'),它将在 DB 上生成单个 join SQL 查询。 (见https://docs.djangoproject.com/en/3.0/ref/models/querysets/#django.db.models.query.QuerySet.values

    并且 values_list 不会生成模型对象,因此它会更快。

    如果您需要将所有数据放在一起,那么最可靠的解决方案就是进行缓存。使用 cron 运行每日脚本,在后台处理您的表格并将其存储在表格中(通过PickleField),如果这是一个选项。 (即使您需要更多最新数据,我也会建议使用后台进程来处理像这样的繁重查询,并在数据库中使用状态标志(键:输入,状态:处理或准备好,数据:PickleField)。)

    如果有大量用户,即使是join-ed 数据库查询也会很慢,使用关系数据库。 您的方法应该是最快的方法之一,因为它只是 4-5 DB 查询 + 处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-16
      • 2013-08-19
      • 2015-04-20
      • 2018-12-04
      • 2019-04-14
      • 2011-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多