Django REST框架序列化器,创建一个对象来封装一些模型字段

huangapple go评论59阅读模式
英文:

django rest framework serializer, create an object to encapsulate some model field

问题

我有一个类似这样的序列化器:

class ListingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Listing
        fields = '__all__'

我的Listing模型有一些字段:name,price,description,street_address,postal_code,city等。

我希望我的序列化器返回一个像这样的对象:

{
    "name": "Prestige",
    "price": 12,
    "description": "lorem ipsum",
    "address": {
        "street": "123 Main St",
        "city": "New York",
        "state": "NY",
        "zip": "10001"
    },
    ...
}

而不是基本的:

{
    "name": "Prestige",
    "price": 12,
    "description": "lorem ipsum",
    "street": "123 Main St",
    "city": "New York",
    "state": "NY",
    "zip": "10001",
    ...
}

我想要封装所有的 "address" 字段到我的响应中的 "address" 对象中。

英文:

I have a serializer which looks like this:

class ListingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Listing
        fields = '__all__'

My Listing model have some field: name, price, description, etc.., street_address, postal_code, city, etc...

I would like my serializer to return an object like this:

{
    "name": "Prestige",
    "price": 12,
    "description": "lorem ipsum",
    "address": {
        "street": "123 Main St",
        "city": "New York",
        "state": "NY",
        "zip": "10001"
    },
    ...
}

instead of the basic:

{
    "name": "Prestige",
    "price": 12,
    "description": "lorem ipsum",
    "street": "123 Main St",
    "city": "New York",
    "state": "NY",
    "zip": "10001"
    ...
}

What I want is encapsulate all "address" field into an "address" object in my response.

答案1

得分: 1

第一种选择是在你的序列化器上覆盖.to_representation

serializers.py

class ListingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Listing
        fields = '__all__'

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        address = {}
        address['street'] = representation.pop('street')
        address['city'] = representation.pop('city')
        address['state'] = representation.pop('state')
        address['zip'] = representation.pop('zip')

        representation['address'] = address
        return representation

或者

另一种选择:

如果可以更改你的模型,也许更好的选择是添加一个Address 模型,并将其与 Listing 关联:

models.py

class Address(models.Model):
    street = models.CharField(max_length=100)
    city = models.CharField(max_length=20)
    state = models.CharField(max_length=5)
    zip = models.CharField(max_length=15)

class Listing(models.Model):
    name = models.CharField(max_length=255)
    price = models.IntegerField()
    description = models.CharField(max_length=255)
    address = models.ForeignKey(Address, on_delete=models.DO_NOTHING, related_name='listings')

serializers.py

class AddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = Address
        exclude = ['id']

class ListingSerializer(serializers.ModelSerializer):
    address = AddressSerializer()

    class Meta:
        model = Listing
        fields = ['name', 'price', 'description', 'address']
英文:

First option is to override .to_representation on your serializer:

serializers.py

class ListingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Listing
        fields = '__all__'

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        address = {}
        address['street'] = representation.pop('street')
        address['city'] = representation.pop('city')
        address['state'] = representation.pop('state')
        address['zip'] = representation.pop('zip')

        representation['address'] = address
        return representation

<h2> Alternatively </h2>

If it is possible to change your models, maybe the better option is to add an Address and associate it with Listing:

models.py

class Address(models.Model):
    street = models.CharField(max_length=100)
    city =models.CharField(max_length=20)
    state = models.CharField(max_length=5)
    zip = models.CharField(max_length=15)

class Listing(models.Model):
    name = models.CharField(max_length=255)
    price = models.IntegerField()
    description = models.CharField(max_length=255)
    address = models.ForeignKey(Address, on_delete=models.DO_NOTHING, related_name=&#39;listings&#39;)

serializers.py

class AddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = Address
        exclude = [&#39;id&#39;]

class ListingSerializer(serializers.ModelSerializer):
    address = AddressSerializer()

    class Meta:
        model = Listing
        fields = [&#39;name&#39;, &#39;price&#39;, &#39;description&#39;, &#39;address&#39;]

huangapple
  • 本文由 发表于 2023年2月26日 22:54:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75572805.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定