【问题标题】:DRF Serializer readable - writeable non-model fieldDRF Serializer 可读 - 可写非模型字段
【发布时间】:2017-12-17 15:50:30
【问题描述】:

在一个使用 Django / DRF 的项目上;我有以下模型结构:

class City(models.Model):
    name = models.CharField(max_length=100)

class Company(models.Model):
    city = models.ForeignKey(City)
    .
    .

以及以下公司模型的序列化器结构:

class CompanySerializer(serializers.ModelSerializer):    
    city_name = serializers.CharField(write_only=True)
    .
    .

    class Meta:
        model = Company
        fields = ('city_name',)

    def create(self, validated_data):

        # Get city
        city_name = validated_data.pop('city_name')
        try: 
            city = City.objects.get(name__iexact=city_name)
        except City.DoesNotExist:
            city = City.objects.create(name=city_name.title())

        company = Company.objects.create(city=city, **validated_data)

        return company

在通过序列化程序创建公司时,用户提供了一个 city_name,如果不存在,我会使用该名称创建一个新城市,如果存在则使用现​​有条目。在这种结构中,我希望能够在返回公司时返回 city_name 字段。它不是模型上的字段,所以我可以正常使用 SerializerMethodField,但我也希望这个字段也是可写的。我在这里有什么选择吗?

【问题讨论】:

  • 请告诉你创建方法
  • @BearBrown 用 create 方法更新了问题

标签: django django-rest-framework


【解决方案1】:

我认为,您的解决方案很简单,添加 source 并删除 write_only

city_name = serializers.CharField(source='city.name')

改成这种方式后,可以在create或update方法中获取城市名,如下:

city_data = validated_data.pop('city')
city_name = city_data.get('name')

【讨论】:

  • 是的,做到了。在 create 方法中,我需要将城市名称作为validated_data.get('city')['name']
  • @OzgurAkcali 可能是关于获取城市名称我不确定,但如果是这样,请为其他将搜索此类解决方案的人更正我的答案
【解决方案2】:

更好的方法是创建两个序列化器

class CitySerializer(serializers.ModelSerializer):
    class Meta:
        model = City
        fields = ('name')

class CompanySerializer(serializers.ModelSerializer):
    city = CitySerializer(write_only=True)

    class Meta:
        model = Company
        fields = ('city',)

    def create(self, validated_data):

        # Get city
        city = validated_data.pop('city')
        try:
            city = City.objects.get(name__iexact=city)
        except City.DoesNotExist:
            city = City.objects.create(name=city.title())

        company = Company.objects.create(city=city, **validated_data)

        return company

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-30
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-16
    • 1970-01-01
    相关资源
    最近更新 更多