从 Django 中的方法获取结果

Fetching results from a method in Django

我的 Django 应用程序 ('crisismode') 有两个模型:事件和操作

我想显示事件和与这些事件相关的操作。对于每个事件,我只想显示活动的动作,所以我使用了一个方法(activactions)。

如何预取这些动作?

class Event(models.Model):
    description = models.CharField(max_length=1000, blank=True)
    active = models.BooleanField(default=True)

    def activeactions(self):
        actions = Action.objects.filter(event=self, active=True)
        if actions:
            return Action.objects.filter(event=self, active=True)
        else:
            return None

class Action(models.Model):
    description = models.CharField(max_length=1000)
    active = models.BooleanField(default=True)
    event = models.ForeignKey(Event, on_delete=models.SET_NULL, related_name="actionsforevent", null=True, blank=True)

我执行以下查询:

events = Event.objects.filter(crisis=crisis, active=True).prefetch_related('actionsforevent')

但是 django-debug-toolbar 告诉我它有多个查询:

FROM "crisismode_action"
 WHERE ("crisismode_action"."active" = true AND "crisismode_action"."event_id" = 323)
 ORDER BY "crisismode_action"."order" ASC, "crisismode_action"."id"
 ASC 10 similar queries.  Duplicated 2 times.

首先我要陈述文档中关于 prefetch_related 的一部分:

prefetch_related, on the other hand, does a separate lookup for each relationship, and does the ‘joining’ in Python.

意味着预取相关会进行多次查询。继续查看您的问题,您有一个方法 activeactions,您可以在其中尝试获取事件的活动操作。您也可以尝试使用与 .prefetch_related('actionsforevent') 相关的预取。这不会像您预期的那样工作,因为您所做的预取与您的方法调用是分开的。此外,您不在此预取中进行过滤。

为了您的使用,我相信您只想预取字段 activeTrue 的操作。您可以使用可以采用查询集的 Prefetch object 来执行此操作:

from django.db.models import Prefetch

events = Event.objects.filter(
    crisis=crisis,
    active=True
).prefetch_related(
    Prefetch(
        'actionsforevent',
        queryset=Action.objects.filter(active=True),
        to_attr='active_actions'
    )
)

我们使用 to_attr 参数指定我们想要自定义属性的结果 active_actions

现在我们可以使用 event.active_actions 简单地访问预取的活动操作。例如:

for event in events:
    for action in event.active_actions:
        print(action.description)