我正在尝试稍微复杂的Django查询集交互,我遇到了障碍。
class A(models.Model):
owner = models.ForeignKey(User)
x = models.CharField(max_length=10)
y = models.CharField(max_length=10)
class B(models.Model):
owner = models.ForeignKey(User)
x = models.CharField(max_length=10)
y = models.CharField(max_length=10)
a_queryset = user.a_set.filter(x__in=("foo", "bar", "baz"))
b_queryset = B.objects.filter(???)
有人碰巧知道生成具有与给定A查询集相同的x / y对的B对象的查询集的有效方法吗?给定一个任意的a_queryset,有没有快速的方法呢?
答案 0 :(得分:0)
您无法使用queryset执行此操作,因为A
和B
即使它们具有间接关系(user
模型),您也不会查询它,因此之间没有关系他们。
你可以使用python内置函数来完成它。
答案 1 :(得分:0)
根据a_queryset
,您可以获得(x, y)
对并使用Q objects
构建查询
首先,从(x, y)
获取a_queryset
个唯一对:
xy_pairs = a_queryset.values_list('x', 'y').distinct()
# [('x1', 'y1'), ('x2', 'y2'), ('x1', 'y2'), ('x2', 'y1')]
对于('x1', 'y1')
对,您可以轻松搜索所有B
个对象,如下所示:
b_objs = B.objects.filter(x='x1', y='y1')
但是,在这里你需要构建一个如下所示的查询:
# (x='x1' AND y='y1') OR (x='x2' AND y='y2') .... etc.
您可以通过创建Q objects
# first create AND queries for different (x, y) pairs
q_and_queries = [(Q(x=x) & Q(y=y)) for x, y in xy_pairs]
#[<Q: (AND: ('x', 'x1'), ('y', 'y1'))>,
# <Q: (AND: ('x', 'x2'), ('y', 'y2'))>,
# <Q: (AND: ('x', 'x1'), ('y', 'y2'))>,
# <Q: (AND: ('x', 'x2'), ('y', 'y1'))>]
# then combine those queries using OR
q_or_query = Q()
for q in q_and_queries:
q_or_query |= q
# <Q: (OR: (AND: ), (AND: ('x', 'x1'), ('y', 'y1')), (AND: ('x', 'x2'), ('y', 'y2')), (AND: ('x', 'x1'), ('y', 'y2')), (AND: ('x', 'x2'), ('y', 'y1')))>
现在,您可以使用最终查询q_or_query
从模型B
获取所需的查询集:
b_queryset = B.objects.filter(q_or_query)