Dor*_*ora 14 python mysql django postgresql
对不起,如果问题听起来很奇怪.我只是想知道当我已经有一个查询集时是否有可能创建新的查询集.
比如这里......
everyone = User.objects.filter(is_active=True) # this would of course return all users that's active
not_deleted = User.objects.filter(is_active=True, is_deleted=False) # return user that's active and not deleted
is_deleted = User.objects.filter(is_active=True, is_deleted=True) # return user that's active and is already deleted
Run Code Online (Sandbox Code Playgroud)
什么我的问题是......对not_deleted
和is_deleted
他们都有积极的是相同的真正everyone
有使用一个可能的方式everyone
,然后以某种方式过滤掉is_deleted=True
或is_deleted=False
?那么我相信如果可能的话,查询会更快更好吗?
所有这三个变量everyone
,not_deleted
并且is_deleted
将被用于别的东西.
希望我能清楚明白我的问题.
提前致谢.
A. *_*arr 17
是的,您可以重用现有的查询集.
everyone = User.objects.filter(is_active=True)
active_not_deleted = everyone.filter(is_deleted=False)
active_is_deleted = everyone.filter(is_deleted=True)
Run Code Online (Sandbox Code Playgroud)
事实上,这个代码块甚至不会对数据库执行查询,因为Django QuerySets被懒惰地评估了.我的意思是,在您确实需要值之前,它不会将查询发送到数据库.这是一个与数据库通信的示例.
everyone = User.objects.filter(is_active=True) # Building SQL...
active_not_deleted = everyone.filter(is_deleted=False) # Building SQL...
active_is_deleted = everyone.filter(is_deleted=True) # Building SQL...
# Example of the whole queryset being evaluated
for user in everyone:
# This will execute the query against the database to return the list of users
# i.e. "select * from user where is_active is True;"
print(user)
# Example of using iterator to evaluate one object at a time from the queryset.
for user in active_not_deleted.iterator():
# This will execute the query for each result, so it doesn't
# load everything at once and it doesn't cache the results.
# "select * from user where is_active is True and is_deleted is False limit 1 offset 0;"
# The offset is incremented on each loop and another query is sent to retrieve the next user in the list.
print(user)
Run Code Online (Sandbox Code Playgroud)
推荐阅读:
作为这个答案的补充,您可以进行单个查询,然后在Python中进行过滤,如果您真的想要的话.请注意,您无法对列表进行后续过滤,因为它们不是QuerySets.
everyone = User.objects.filter(is_active=True)
active_not_deleted = list(filter(lambda user: user.is_deleted is False), list(everyone))
active_is_deleted = list(filter(lambda user: user.is_deleted is True), list(everyone))
Run Code Online (Sandbox Code Playgroud)
在最后一个示例中,everyone
是一个查询集,active_not_deleted
并且active_is_deleted
是User对象的Python列表.查询集everyone
将仅在第一次list(everyone)
调用中计算一次,然后缓存结果.
not_deleted = User.objects.filter(active=True).filter(is_deleted=False)
Run Code Online (Sandbox Code Playgroud)
@Cory Madden 已经回答了。User.objects.filter(active=True)
返回查询集。所以你可以添加过滤方法。active_users.filter(is_deleted=False)
from django.db.models import Q
not_deleted = User.objects.filter(Q(active=True) & Q(is_deleted=False)
Run Code Online (Sandbox Code Playgroud)
管理复杂的查询集更容易。如果要过滤userID不是3怎么办?您可以使用 Q simplee 之类的User.objects.filter(Q(active=True) & ~Q(id = 3))
回答你的评论,
无论是否使用 Q,它都有相同的原始查询。
SELECT ... FROM ...
WHERE ("auth_user"."active" = True AND "auth_user"."is_deleted" = False)
Run Code Online (Sandbox Code Playgroud)
数据库性能与您访问数据库以提取数据的频率有关,或者当您通过 FK 关系提取某些内容时是否使用了像“加入”这样的繁重方法。所以使用 Q 与否不会给您带来性能差异,因为它具有相同的查询语句。
此外,
user = User.objects.filter(active=True)
not_deleted = User.objects.filter(active=True).filter(is_deleted=False)
user = User.objects.filter(active=True)
not_deleted = user.filter(is_deleted=False)
Run Code Online (Sandbox Code Playgroud)
不会给你性能差异。
查询集是懒惰的。user
和not_deleted
变量只有查询集字符串。当您像上面一样定义变量时,它不会立即访问数据库。无论如何,您将为每个变量击中 3 次。
你能做的最好的事情是:
active_users = User.objects.filter(active=True)
not_deleted = active_users.filter(is_deleted=False)
deleted = active_users.filter(is_deleted=True)
Run Code Online (Sandbox Code Playgroud)
所以如果我理解正确的话,你的问题的答案可能是肯定的。
归档时间: |
|
查看次数: |
15064 次 |
最近记录: |