如何扩展Django Queryset的select_related函数的作用域,使其包括与与原始表相关的表相关的表

问题描述 投票:0回答:1

这是我的models.py的样子

    class Branches(models.Model):
        def __str__(self):
            return self.location

        location = models.CharField(max_length=256, unique=True)


    class Daily_Infos(models.Model):
        class Meta:
            unique_together = ["date", "branch_id"]

        def __str__(self):
            return str(self.date) + " " + str(self.branch_id)

        branch_id = models.ForeignKey(Branches, related_name='daily_info', on_delete=models.CASCADE)
        date = models.DateField()

    class Branch_Prices(models.Model):
        def __str__(self):
            return str(self.branch_id) + " " + str(self.menu_item_id) + " " + str(self.price)

        branch_id = models.ForeignKey(Branches, related_name='prices', on_delete=models.CASCADE)
        menu_item_id = models.ForeignKey(Menu_Items, related_name='prices', on_delete=models.CASCADE)
        price = models.FloatField()

    class Sold_Menu_Items(models.Model):
        def __str__(self):
            return str(self.branch_price_id) + " " + str(self.daily_info_id) + " " + str(self.quantity)

        daily_info_id = models.ForeignKey(Daily_Infos, related_name='sold_menu_items', on_delete=models.CASCADE)
        branch_price_id = models.ForeignKey(Branch_Prices, related_name='sold_menu_items', on_delete=models.CASCADE)
        quantity = models.IntegerField()

    class Menu_Items(models.Model):
        def __str__(self):
            return str(self.name) + " " + str(self.size)

        name = models.CharField(max_length=256)
        size = models.CharField(max_length=64)
        start_date = models.DateField()
        is_active = models.BooleanField()

在我的views.py中,我具有此功能:

def view_sold_items_all(request):
    sold_menu_items = Sold_Menu_Items.objects.select_related('branch_price_id','daily_info_id')
    refined_sold_menu_items = []
    for smi in raw_sold_menu_items:
        menu_item = []
        menu_item.append(smi.daily_info_id.date)
        menu_item.append(smi.quantity)
        menu_item.append(smi.branch_price_id.branch_id.location)
        menu_item.append(smi.branch_price_id.menu_item_id.name)
        menu_item.append(smi.branch_price_id.menu_item_id.size)

        refined_sold_menu_items.append(menu_item)
    return render(request, 'view_all.html', {
        'sold_items':refined_sold_menu_items
        })

根据我的理解,下面的代码(在我的views.py文件中)将允许Django仅查询我的数据库一次。

sold_menu_items = Sold_Menu_Items.objects.select_related('branch_price_id','daily_info_id')

在for循环期间,它将不会继续查询数据库的两行:

menu_item.append(smi.daily_info_id.date)
menu_item.append(smi.quantity)

但是,对于其他三个附加项,我认为Django仍在查询数据库,因为select_related不涉及该问题,因为select_related不直接与Sold_Menu_Items表关联。

我的问题是,如何使我的代码更高效?我打算让Django仅查询数据库一次,以便在for循环的三个附加部分中,它不需要继续查询数据库。我在想,也许我可以在Branch_Prices表上第二次使用select_related。但是,我不知道该怎么做,我什至不知道这是否是使我的代码更高效的正确方法。

django django-models django-views django-queryset django-orm
1个回答
0
投票

我相信我能够回答自己的问题。这是正确的方法吗?我对views.py进行了一些编辑。

© www.soinside.com 2019 - 2024. All rights reserved.