2016-03-29 132 views
1

我想要做一個稍微複雜的Django queryset交互,我已經遇到了障礙。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(???) 

任何人都知道發生的一種有效的方式來生成具有相同的x/y對給出一個QuerySet A B對象的查詢集?給定一個任意的a_queryset有沒有一種快速的方法?

回答

0

你不能使用查詢集它這樣做,因爲,AB即使他們有間接的關係(user模型)你是不是查詢使用它,所以沒有它們之間的關係。

你可以使用python內建函數來做到這一點。

0

鑑於a_queryset你可以得到(x, y)對,並建立使用Q objects

首先查詢,從a_queryset得到(x, y)唯一對:

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') 

但是,在這裏你需要建立一個查詢看起來是這樣的:通過創建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')))> 

現在

# (x='x1' AND y='y1') OR (x='x2' AND y='y2') .... etc. 

,你可以做到這一點,你可以用最終的查詢q_or_query得到來自型號B的所需查詢集:

b_queryset = B.objects.filter(q_or_query)