2

Существует сценарий, в котором я хочу показать общую покупку пользователя. Я использовал @property внутри моделей userprofiles. К счастью, он работает так, как я ожидал. Но я хочу использовать prefetch_related для оптимизации запросов django, поскольку общая покупка пользователя рассчитывается из order_history, которая имеет отношение ManyToMany с OrderMenu.Не удалось выяснить использование prefetch_related в django

Как я это сделал?

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 
    slug = models.SlugField(unique=True,blank=True,null=True) 
    restaurant = models.ManyToManyField(Restaurant, blank=True) 
    order_history = models.ManyToManyField(OrderMenu, blank=True) 
    # favorites = models.ManyToManyField(Restaurant) 
    is_owner = models.BooleanField(default=False) 

    @property 
    def total_purchase(self): 
     total_purchase = 0 
     # user_order = UserProfile.objects.prefetch_related('order_history').get(slug=self.slug) 
     userprofile = UserProfile.objects.get(slug=self.slug) 
     user_order = userprofile.order_history.all() 
     for usr in user_order: 
      total_purchase += usr.get_cost() 
     return total_purchase 

В этом растворе, не

профиль_пользователя = UserProfile.objects.get (пробкового = self.slug) user_order = userprofile.order_history.all()

является эквивалентно

user_order = UserProfile.objects.prefetch_related ('order_history'). получаем (пробкового = self.slug)

Я так сильно смущен с prefetch_related. Может ли кто-нибудь прозвать меня простым языком? Извините, я не носитель английского языка.

ответ

2

Разница между этими двумя

В случае базы данных

userprofile = UserProfile.objects.get(slug=self.slug) #hits

Этот запрос получает объект UserProfile, основываясь на состоянии из базы данных снова

user_order = userprofile.order_history.all() #hits базы данных

Этот запрос получает запрос пользователя user_order с использованием userprofile objec t удалять базу данных снова.

т.е. профиль_пользователя хитов базы данных, а также user_order

В этом случае, однако

user_order=UserProfile.objects.prefetch_related('order_history').get(slug=self.slug)

user_order QuerySet набор возвращает не только профиль объекта, но и «order_history» QuerySet, который связан с объектом UserProfile в одном попадании в базу данных. Теперь, когда вы обращаетесь к querset «order_history» с объектом user_order, он не попадет в базу данных, но получит запрос «order_history» из предварительно загруженного кеша QuerySet «user_order». подробнее об этом here.

+1

Это то, что я понимаю о prefetch_related, поэтому я сделал user_order = UserProfile.objects.prefetch_related ('order_history'). Get (slug = self.slug) и перебирает user_order для вычисления общей стоимости с использованием total + usr.get_cost() но я получаю сообщение об ошибке «Объект UserProfile» не является итерабельным – Serenity

+0

Я также добавил часть модели. Почему я получаю ошибку в объекте «UserProfile», не является итерабельным, когда я перебираю user_order, который использует prefetch_related для извлечения функции get_cost из OrderMenu? – Serenity

+1

user_order - это единственный объект UserProfile, это не набор запросов, вы не можете выполнять итерацию с помощью user_order. если вы хотите итерации, не используйте get, user filter, чтобы получить queryset вместо объекта. что-то вроде user_order = UserProfile.objects.prefetch_related ('order_history'). filter (slug = self.slug), который возвращает queryset (список объектов UserProfile на основе соответствия). – javed

 Смежные вопросы

  • Нет связанных вопросов^_^