【问题标题】:how to get a record via the ManyToMany link如何通过多对多链接获取记录
【发布时间】:2021-09-20 19:44:33
【问题描述】:

1

我想通过订单模式获取餐厅的邮箱。我该怎么做?

我的models.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

我是这样下单的 视图.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,
    )

【问题讨论】:

  • 您的Order 可以在多家餐厅享用多餐,或者至少它是这样建模的)。您的应用程序是否主动阻止了这种情况?
  • @WillemVanOnsem 我的英语不好。但我想说,订单中可以有很多来自不同餐厅的餐点,这是真的。如果我正确理解了您的问题

标签: python django django-models django-views


【解决方案1】:

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

您可以通过以下方式检索相关Restaurants 的QuerySet

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

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

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

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

例如,您可以使用它来调用 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)

您还可以使用作为Order“成员”的Meals:

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

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

【讨论】:

  • 我需要在这个函数中获取邮件:cooking_meal_notification(restaurant_email=???)
  • 我以这种方式创建订单:对于餐厅,itertools.groupby(CartMeal.objects.filter(cart=cart).order_by('meal__restaurant') 中的 cart_meals,lambda s: s.meal。 restaurant): order = Order.objects.create(...) order.cart_meal.set([cart_meal for cart_meal in cart_meals])
  • @nikitaex:第二个代码片段是电子邮件地址的集合。因此,您可以使用循环 (for email in last_queryset: cooking_meal_notification(restaurant_email=email)
  • @nikitaex:查看更新。
  • 你能看一下帖子的更新吗?
猜你喜欢
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 2011-01-01
相关资源
最近更新 更多