2016-11-23 104 views
1

我已经在这些表中一个Django应用程序:Django的过滤器外键逆转

class Order(models.Model): 
    ... 

class SubOrder1(models.Model): 
    order = models.ForeignKey(Order, blank=True, null=True) 

class SubOrder2(models.Model): 
    order = models.ForeignKey(Order, blank=True, null=True) 

... 

我怎么能写上订单查询导致仅具有至少一个相关SubOrder1或SubOrder2的命令?我需要这样的东西

Order.objects.filter(suborder__count__ge = 1, ...) 

我使用Django = 1.9.2和Python 3.4.1 =

回答

2

使用isnull现场查询:

orders_with_suborders = Order.objects.filter(
    Q(suborder1__isnull=False) | Q(suborder2__isnull=False) 
) 
+0

谢谢,那就是我一直在寻找的。 – user2194805

+0

除非使用'distinct()',否则这可能会导致重复。 – Alasdair

1

Annotate your queryset与相关模型的罪状:

from django.db.models import Count 

queryset = Order.objects.annotate(
    num_suborder1=Count('suborder1', distinct=True), 
    num_suborder2=Count('suborder2', distinct=True), 
) 

查看关于combining multiple aggregations的文档以解释我们为什么需要distinct=True

然后,您可以使用Q过滤其中任一计数位于leas t 1.

orders_with_suborders = queryset.filter(
    Q(num_suborder1__gte=1) | Q(num_suborder1=1__gte=1), 
) 
-1

你可以从Order得到SubOrder1

order = Order.objects.get(pk=pk) 
suborders1 = order.suborder1_set.all() 

然后你就可以通过亚目迭代:

for suborder in suborders1: 
    print (suborder) 

希望它可以帮助你

0

一个解决方案,我只是发现会是这样的:

Order.objects.filter(suborder1__id__gt = -1) 

,我可以SubOrder2使用相同。这是一个解决方案,但不是真正的djangonic。有没有更好的解决方案?

+0

注意,你可能会得到每个亚目重复的结果。你可以使用'distinct()'来避免这种情况。 – Alasdair

+0

是的。谢谢! 。 – user2194805