Django 查询仅过滤具有特定字段名称的第一个对象
Django query to filter only first objects with particular field names
型号
class UserAction(models.Model):
ACTION_CHOICES = (
("LogIn", "Entered"),
("LogOut", "Gone Out"),
("Away", "Away from Computer"),
("Busy", "Busy"),
("DoNotDisturb", "Do not disturb"),
("Online", "Online and Available"),
)
action_name = models.CharField(choices=ACTION_CHOICES, default="LogIn")
user = models.ForeignKey(Profile, related_name="actions")
action_time = models.DateTimeField(default=timezone.now(), editable=False)
class Profile(models.Model):
name = models.CharField(max_length=120)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(default=timezone.now())
我需要查询 UserAction,这样我只需要每个用户的最后一个 UserAction。我的解决方案太耗时了。这就是寻找优化答案的原因。
您可以使用 Subquery
expression [Django-doc]:
注释 Profile
from django.db.models import OuterRef, Subquery
Profile.objects.annotate(
last_action=<strong>Subquery(</strong>
UserAction.objects.filter(
user_id=OuterRef('pk')
).order_by('-action_time').values('action_name')[:1]
<strong>)</strong>
)
查询集中的 Profile
将有一个额外的属性 .last_action
与最后一个相关的 UserAction
.
的 action_name
Note: Django's DateTimeField
[Django-doc]
has a auto_now_add=…
parameter [Django-doc]
to work with timestamps. This will automatically assign the current datetime
when creating the object, and mark it as non-editable (editable=False
), such
that it does not appear in ModelForm
s by default.
型号
class UserAction(models.Model):
ACTION_CHOICES = (
("LogIn", "Entered"),
("LogOut", "Gone Out"),
("Away", "Away from Computer"),
("Busy", "Busy"),
("DoNotDisturb", "Do not disturb"),
("Online", "Online and Available"),
)
action_name = models.CharField(choices=ACTION_CHOICES, default="LogIn")
user = models.ForeignKey(Profile, related_name="actions")
action_time = models.DateTimeField(default=timezone.now(), editable=False)
class Profile(models.Model):
name = models.CharField(max_length=120)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(default=timezone.now())
我需要查询 UserAction,这样我只需要每个用户的最后一个 UserAction。我的解决方案太耗时了。这就是寻找优化答案的原因。
您可以使用 Subquery
expression [Django-doc]:
Profile
from django.db.models import OuterRef, Subquery
Profile.objects.annotate(
last_action=<strong>Subquery(</strong>
UserAction.objects.filter(
user_id=OuterRef('pk')
).order_by('-action_time').values('action_name')[:1]
<strong>)</strong>
)
查询集中的 Profile
将有一个额外的属性 .last_action
与最后一个相关的 UserAction
.
action_name
Note: Django's
DateTimeField
[Django-doc] has aauto_now_add=…
parameter [Django-doc] to work with timestamps. This will automatically assign the current datetime when creating the object, and mark it as non-editable (editable=False
), such that it does not appear inModelForm
s by default.