Как расширить охват функции select_related Django Queryset, чтобы она включала таблицу, связанную с таблицей, связанной с исходной таблицей - PullRequest
0 голосов
/ 16 марта 2020

Вот так выглядит мой 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 l oop он не будет продолжать запрашивать базу данных для двух строк:

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

Однако для остальных трех добавлений, я думаю, Django все еще запрашивает базу данных, потому что select_related не покрывает это, поскольку она не связана напрямую с таблицей Sold_Menu_Items.

Мой вопрос: как мне сделать мой код более эффективным? Я планировал Django запросить базу данных только один раз, чтобы в трех добавлениях для l oop не требовалось продолжать запрашивать мою базу данных. Я думал, что, возможно, я мог бы использовать select_related во второй раз в таблице Branch_Prices. Однако я не знаю, как это сделать, и даже не знаю, является ли это правильным способом go по повышению эффективности моего кода.

1 Ответ

0 голосов
/ 16 марта 2020

Мне кажется, я смог ответить на свой вопрос. Это правильный способ сделать это? Я внес некоторые изменения в мои views.py.

def view_sold_items_all(request):
    raw_sold_menu_items = Sold_Menu_Items.objects.select_related(
        'daily_info_id',
        'branch_price_id__branch_id', 
        'branch_price_id__menu_item_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.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)
        menu_item.append(smi.quantity)
        refined_sold_menu_items.append(menu_item)
    return render(request, 'view_all.html', {
        'sold_items':refined_sold_menu_items
        })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...