我的问题很简单:在Django应用中,我有一个表Users
和一个表StatusUpdates
。在StatusUpdates
表中,我有一个列user
,它是指向Users
的外键。如何进行表达式的搜索:
users.filter(latest_status_update.text__contains='Hello')
修改
请原谅我的不清楚。我想提出的查询类似于"向我提供最新状态更新包含文字' hello'"的所有用户。在Django代码中,我会做以下(这是非常低效和丑陋的):
hello_users = []
for user in User.objects.all():
latest_status_update = StatusUpdate.objects.filter(user=user).order_by('-creation_date')[0]
if latest_status_update.text.contains('Hello'):
hello_users.append(user)
return hello_users
编辑2:
我已经找到了解决方案,但自从我被问及以下是这些模型的重要部分:
class User(models.Model):
...
class StatusUpdate(models.Model):
user = models.ForeignKey(User)
text = models.CharField(max_length=140)
creation_date = models.DateTimeField(auto_now_add=True, editable=False)
....
答案 0 :(得分:2)
好的,我想我明白了:
from django.db.models import Max, F
User.objects\
.annotate(latest_status_update_id=Max('statusupdate__id'))\
.filter(
statusupdate__id=F('latest_status_update_id'),
statusupdate__text__icontains='hello'
)
有关详细信息,请参阅this section of the Django documentation。
请注意: 我最后改变了我的策略并解决了最高ID意味着最新更新的策略。这是因为我意识到用户可以同时发布两个更新,这会破坏我的查询。
答案 1 :(得分:0)
不确定我明白了,您是否正在尝试做类似
的事情StatusUpdates.objects.select_related("user").filter(text__contains = "hello").order_by("-updated").first()
这将返回最后修改的StatusUpdate(如果您有一个名为updated的字段,用于存储上次修改的时间),该字段在文本字段中包含“Hello”。如果StatusUpdates都不包含该字符串,则它将返回None。
然后你可以做
latest = StatusUpdates.objects.select_related("user").filter(text__contains = "hello").order_by("-updated").first()
#then if you needed the user too
if latest is not None:
user = latest.user #which does not call the DB again since you selected related`
如果这不是您所需要的,请提供更多详细信息(型号)并说明您的需求
答案 2 :(得分:0)
latest_status_updates = filter(lambda x: x.text.contains('hello'),
[
user.statusupdates_set.order_by('-creation_date').first()
for user in User.objects.all()
]
)
users = list(set([status_update.user for status_update in latest_status_updates]))
编辑: 现在,我首先将每个用户的所有最新状态更新都放入一个列表中,然后通过StatusUpdate类中的文本字段进行过滤。在第二行中,我从过滤后的状态更新中提取用户,然后生成唯一的用户列表。
我希望这有帮助!