【问题标题】:How do I achieve the equivalent of LEFT JOIN in Django - Nested Serializers in Django如何在 Django 中实现相当于 LEFT JOIN - Django 中的嵌套序列化程序
【发布时间】:2021-10-06 19:19:40
【问题描述】:

我有下面的型号规格。 MailingList 是 Customer 和 Email 之间的参考表/模型。它还有其他几个属性,在应用过滤器时很有用。我的目标是应用一些过滤器然后返回序列化结果。结果应包括客户的订单。

models.py

class Email(models.Model):
    name = models.CharField(max_length=300, unique=True)

class Item(models.Model):
    name = models.CharField(max_length=50)

class Customer(models.Model):
    passport_number = models.CharField(max_length=20, unique=True)
    name = models.CharField(max_length=20)

class Order(models.Model):
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)

class MailingList(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
    email = models.ForeignKey(Email, on_delete=models.CASCADE)

serializer.py

class CustomerSerializer(serializers.ModelSerializer):
    passport = serializers.CharField(source='customer.passport_number')
    customer_name = serializers.CharField(source='customer.name')

    # I want to add the orders for each customer too

    class Meta:
        model = MailingList
        fields = ['passport', 'customer_name']

views.py

class CustomerViewSet(viewsets.ViewSet):
    def list(self, request):
        queryset = MailingList.objects.filter(some_filters).prefetch_related('customer')

        serializer = CustomerSerializer(queryset, many=True)
        return serializer.data

这是我目前收到的回复

[
    {passport: 48, name: "Collins"},
    {passport: 32, name: "Kate"}
]

这是我想要得到的回应

[
    {passport: 48, name: "Collins", orders: {"1": "Hp EliteDisplay", "2": "Sony a7iii"}},
    {passport: 32, name: "Kate" orders: {}}
]

问题:如何在同一响应中嵌入订单?

【问题讨论】:

  • 这能回答你的问题吗? LEFT JOIN Django ORM
  • 没有。实际上,我在寻找解决方案时看到了这一点。我的情况不同,详情在问题和代码示例中

标签: python django postgresql


【解决方案1】:

使用 https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

class CustomerSerializer(serializers.ModelSerializer):
    passport = serializers.CharField(source='customer.passport_number')
    customer_name = serializers.CharField(source='customer.name')
    orders = serializers.SerializerMethodField()

    def get_orders(self, mailing_list):
      return OrderSerializer(queryset=mailing_list.customer.order_set.all(), many=True)

    # I want to add the orders for each customer too

    class Meta:
        model = MailingList
        fields = ['passport', 'customer_name', 'orders']

【讨论】:

    猜你喜欢
    • 2016-03-01
    • 2015-12-16
    • 2016-10-01
    • 2019-06-11
    • 2020-02-01
    • 1970-01-01
    • 2018-06-23
    • 2018-05-20
    • 2015-04-17
    相关资源
    最近更新 更多