简体   繁体   English

Django Rest 框架 - 嵌套关系的过滤字段

[英]Django Rest Framework - Filter fields of nested relationships

I want to return a nested representation of Customer with Image objects, where a Customer can have many Images .我想返回带有Image对象的Customer的嵌套表示,其中Customer可以有很多Images

Currently, the GET request returns a list of ALL images from the Image queryset for each Customer object as shown below.目前,GET 请求从每个Customer object 的Image查询集中返回所有图像的列表,如下所示。 How can I show only related Image (s) for each Customer object in a list instead?我怎样才能在列表中只显示每个Customer object 的相关Image

# The 'images' field currently returns all images rather than related images to the customer id.
[
   {
       'id': 1,
       'name': 'John Doe',
       'images': [
           {'id': 1, 'name': 'foo.jpg', 'customer': 1},
           {'id': 2, 'name': 'bar.jpg', 'customer': 2},
           {'id': 3, 'name': 'foobar.jpg', 'customer': 3},
           ...
       ]
   },
   {
       'id': 2,
       'name': 'Jane Doe',
       'images': [
           {'id': 1, 'name': 'foo.jpg', 'customer': 1},
           {'id': 2, 'name': 'bar.jpg', 'customer': 2},
           {'id': 3, 'name': 'foobar.jpg', 'customer': 3},
           ...
       ]
   },
   ...
]

This is my current setup这是我目前的设置

Example Models示例模型

class Customer(models.Model):
      name = models.CharField()

class Image(models.Model):
      name = models.CharField()
      customer = models.ForeignKey(
        Customer, on_delete=models.CASCADE)

Example Serializers示例序列化程序

class CustomerSerializer(serializers.ModelSerializer):
    # My Customer nested relationship is expressed using ImageSerializer as a field
    images = ImageSerializer(many=True)

    class Meta:
        model = Customer
        fields = ('id', 'name', 'images')
        read_only_fields = ('id',)

class ImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Image
        fields = '__all__'
        read_only_fields = ('id',)

Please let me know if my question is unclear and I will update my question.如果我的问题不清楚,请告诉我,我会更新我的问题。 Thank you.谢谢你。

You need to use the related name as the field for the reverse foreign key.您需要使用相关名称作为反向外键的字段。

In your case this would be;在您的情况下,这将是;

class CustomerSerializer(serializers.ModelSerializer):

    class Meta:
        model = Customer
        fields = ('id', 'name', 'image_set')
        read_only_fields = ('id',)

Consider it like a reverse FK query - Customer.objects.first().image_set.all()将其视为反向 FK 查询 - Customer.objects.first().image_set.all()


DRF Docs on this are here;关于此的 DRF 文档在这里; Reverse Relations 反向关系

Django docs on reversing relationships are here Django 反转关系的文档在这里


Using the _set reverse lookup like this is the django default.像这样使用_set反向查找是 django 默认值。 It's possible that you may add your own related_name to a relationship.您可以将自己的related_name添加到关系中。

An example from the django docs;来自 django 文档的示例;

# Declare the ForeignKey with related_query_name
class Tag(models.Model):
    article = models.ForeignKey(
        Article,
        on_delete=models.CASCADE,
        related_name="tags",
        related_query_name="tag",
    )
    name = models.CharField(max_length=255)

# That's now the name of the reverse filter
Article.objects.filter(tag__name="important")

For your example you might add something like;对于您的示例,您可以添加类似的内容;

class Image(models.Model):
    name = models.CharField()
    customer = models.ForeignKey(
        Customer,
        on_delete=models.CASCADE,
        related_name="images"
    )

The django default of Customer.image_set will still work, but you can then do Customer.images.all() because you've defined that related_name for the relationship. Customer.image_set的 django 默认值仍然有效,但您随后可以执行Customer.images.all() ,因为您已经为关系定义了related_name

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM