我是一个C++开发者,也是python的新手,只是在学习django教程。
我想知道如何通过反向引用的信息过滤查询集。
下面是我的模型。
# models.py
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
现在,我想获取Question
的查询集,其中pub_date
是从现在起过去的,并且被任何Choice
引用。
下面是我的尝试。
# First method
question_queryset = Question.objects.filter(pub_date__lte=timezone.now())
for q in question_queryset.iterator():
if Choice.objects.filter(question=q.pk).count() == 0:
print(q)
# It works. Only @Question which is not referenced
# by any @Choice is printed.
# But how can I exclude @q in @question_queryset?
# Second method
question_queryset = Question.objects.filter(pub_date__lte=timezone.now()
& Choice.objects.filter(question=pk).count()>0) # Not works.
# NameError: name 'pk' is not defined
# How can I use @pk as rvalue in @Question.objects.filter context?
是因为我不熟悉Python语法吗?还是因为处理数据的方法本身就有问题?你有什么好主意可以在不改变模型的情况下解决我的问题吗?
编辑:我刚刚找到了第一种方法。
# First method
question_queryset = Question.objects.filter(pub_date__lte=timezone.now())
for q in question_queryset.iterator():
if Choice.objects.filter(question=q.pk).count() == 0:
question_queryset = question_queryset.exclude(pk=q.pk)
一个新的关切出现了:如果@Question的行数是n,@Choice的行数是m,那么上面的方法要花O(n * m)次,对吗?有什么方法可以提高性能吗?会不会是我处理数据的方式有问题?或者是数据的结构有问题?
2条答案
按热度按时间k97glaaz1#
下面是有关如何反向跟踪关系的文档。以下查询将生成相同的结果:
依赖Django ORM可能比编写自己的过滤器更好,我相信在最好的场景中时间复杂度是一样的。
与设计有关,这种关系会导致数据库中的重复,不同的问题有时会有相同的答案。我可能会选择多对多的关系。
vsnjm48y2#
这不是查询集的工作方式,迭代查询集就是迭代数据库返回的查询集中的每个数据,你不需要使用iterate()
我没测试过。但应该能用。