如何使用2个外键过滤Django-Model?

时间:2016-01-20 18:18:40

标签: python django django-models

我有以下型号:

class Event(models.Model):
    event = models.ForeignKey(EventType)
    name = models.CharField(max_length=128, null=True, blank=True)

class Order(models.Model):
    requester = models.CharField(max_length=128)
    email = models. EmailField()
    phone = models.CharField(max_length=13)
    payment_date = models.DateTimeField()
    added = models.DateTimeField(auto_now_add=True)
    viewed = models.BooleanField(default=False)
    password = models.CharField(max_length=6,blank=True,null=True)

class Picture(models.Model):
    event = models.ForeignKey(Event)
    image = models.ImageField(upload_to='media')
    show_name = models.CharField(max_length=128, blank=True, null= True)
    file_name = models.CharField(max_length=128, blank=True, null=True)

class OrderItem(models.Model):
    order = models.ForeignKey(Order)
    picture = models.ForeignKey(Picture)
    amount = models.PositiveSmallIntegerField()

我正在尝试计算属于每个事件的所有订单。有时,许多事件中都有订单,这就是我不能在订单和事件之间使用FK的原因。

我试图获取所有“OrderItem”,然后转到Picture,然后转到Event,所以如果某个订单中的图片属于某个事件,则计数器会计算一个。但这就是我被卡住的地方。

这是我的view.py:

的一部分
active_events = Event.objects.filter(is_active=True)
pictures_detail = OrderItem.objects.all()
picture = Picture.objects.all()
print_order = PrintOrder.objects.all()
context_dict['print_order'] = {}

for event in active_events:
    print_order_counter = 0
    for detail in pictures_detail:
        for pic in picture:
            for order in print_order:
                print_order_counter += 1
                for orders in pictures_detail:
                    context_dict['print_order'].update(
                        {event.id : print_order_counter})

任何帮助将不胜感激。

提前谢谢。

2 个答案:

答案 0 :(得分:1)

如果没有完整的图片,您似乎正在使用复杂的方案。对模型的字段定义使用Observer关键字参数,可以查找所有与反向相关的外键对象;这可以根据外键设置并由父模型调用。

related_name

答案 1 :(得分:0)

之前的答案不正确。你将以这种方式杀死你的数据库。如果您需要的信息不仅仅是计数,那么您应该使用prefetch_related,否则在循环时它将在每次迭代中命中数据库。

如果您需要多个订单来处理多个事件,那么就会有多对多关系https://docs.djangoproject.com/en/dev/topics/db/examples/many_to_many/

由于您只需要计算活动订单,因此更容易。 让我们使用唯一related_name

命名每个外键
class Picture(models.Model):
    event = models.ForeignKey(Event, related_name='event_pictures')

class OrderItem(models.Model):
    order = models.ForeignKey(Order, related_name='ordered_items')
    picture = models.ForeignKey(Picture, related_name='picture_orders')

现在,我现在在数据库中导航有点困难,但你应该可以这样做:

Events.objects.annotate(Count('event_pictures__picture_orders__order'))

可能需要进行修改或添加不同的修改。但是你绝对应该使用这种方法而不是python中的任何迭代。这将完全杀死应用程序。但是,如果您绝对需要,那么请务必使用prefetch_related('event_pictures__picture_orders__order'),如前所述。