首页 > 解决方案 > 如何通过多对多链接获取记录

问题描述

1

我想通过订单模型获取餐厅的电子邮件。我怎样才能做到这一点?

我的模型.py:


class Order(models.Model):
    cart_meal = models.ManyToManyField(CartMeal, null=True, blank=True)

class CartMeal(models.Model):
    meal = models.ForeignKey(Meal, verbose_name='Meal', on_delete=models.CASCADE)

class Meal(models.Model):
    restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE, null=True)

class Restaurant(models.Model):
    email = models.EmailField()

我需要通过订单访问 restaurant.email。我试图这样做,但它不起作用:order.cart_meal.model.meal.restaurant.email

我以这种方式得到订单views.py

@action(methods=['PUT'], detail=False, url_path='current_customer_cart/add_to_order')
    def add_cart_to_order(self, *args, **kwargs):
        cart = Cart.objects.get(owner=self.request.user.customer)
        cart_meals = CartMeal.objects.filter(cart=cart)
        data = self.request.data

        for restaurant, cart_meals in itertools.groupby(CartMeal.objects.filter(cart=cart).order_by('meal__restaurant'),
                                                        lambda s: s.meal.restaurant):
            order = Order.objects.create(
                customer=self.request.user.customer,
                first_name=data['first_name'],
                last_name=data['last_name'],
                phone=data['phone'],
                address=data.get('address', self.request.user.customer.home_address),
            )
            order.cart_meal.set([cart_meal for cart_meal in cart_meals])
            
            cooking_meal_notification(**restaurant_email=???**)

在调用最后一个方法cooking_meal_notification时,我需要获取餐厅的电子邮件

发件人.py

def cooking_meal_notification(restaurant_email, meal):
    send_mail(
        'An order has been received',
        meal,
        'kudlasevich.nikita@gmail.com',
        [restaurant_email],
        fail_silently=False,
    )

标签: pythondjangodjango-modelsdjango-views

解决方案


可以有多个Restaurants,因为一个Order可以包含由不同Restaurants 生产的多餐。

您可以使用以下方法检索QuerySet相关Restaurants:

Restaurant.objects.filter(
    meal__cartmeal__order=order
).distinct()

因此,我们可以通过以下方式检索这些Restaurants 的电子邮件地址:

Restaurant.objects.filter(
    meal__cartmeal__order=order
).values_list('email', flat=True).distinct()

因此,这会产生Restaurant与该订单相关的 s 的电子邮件地址的可迭代。

例如,您可以使用它来调用调用函数,例如cooking_meal_notification

qs = Restaurant.objects.filter(
    meal__cartmeal__order=order
).values_list('email', flat=True).distinct()

for email in qs:
    cooking_meal_notification(email)

您还可以使用作为Meal“成员”的 s Order

qs = Meal.objects.filter(
    cartmeal__order=order
).select_related('restaurant')

for meal in qs:
    cooking_meal_notification(meal.restaurant.email, meal)

推荐阅读