【问题标题】:Django REST Framework: nested serializer not properly validating dataDjango REST Framework:嵌套序列化程序未正确验证数据
【发布时间】:2018-07-07 15:21:07
【问题描述】:

我是 DRF(和 Django)的新手,正在尝试创建一个能够验证以下请求数据的嵌套序列化程序:

{
    "code": "12345",
    "city": {
        "name": "atlanta",
        "state": "Georgia"
    },
    "subregion": {
        "name": "otp north"
    }
}

为了简化客户端的操作,我希望通过这个单一请求在数据库中创建多条记录:

  • 城市(如果不存在匹配的城市)
  • 子区域(如果不存在匹配的子区域)
  • 引用城市和(可选)子区域的 CodeLog

型号:

class City(models.Model):
    name = models.CharField(max_length=75, unique=True)
    state = models.CharField(max_length=50, blank=True)

class Subregion(models.Model):
    city = models.ForeignKey(City)
    name = models.CharField(max_length=75)

class CodeLog(models.Model):
    code = models.CharField(max_length=10)
    city = models.ForeignKey(City)
    subregion = models.ForeignKey(Subregion, blank=True, null=True)

序列化器:

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

class SubregionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Subregion
        fields = ('name',)

class CodeLogSerializer(serializers.ModelSerializer):
    city = CitySerializer()
    subregion = SubregionSerializer(required=False)

    class Meta:
        model = CodeLog
        fields = ('code', 'city', 'subregion')

    # This is where I'm having troubles
    def create(self, validated_data):
        city_data = validated_data.pop('city', None)
        subregion_data = validated_data.pop('subregion', None)
        if city_data:
            city = City.objects.get_or_create(**city_data)[0]
        subregion = None
        if subregion_data:
            subregion = Subregion.objects.get_or_create(**subregion_data)[0]

        code_log = CodeLog(
            code=validated_data.get('code'),
            city=city,
            subregion=subregion
        )
        code_log.save()
        return code_log

查看:

class CodeLogList(APIView):
    serializer_class = CodeLogSerializer

    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

我能够使用平面请求结构使其工作,事实证明嵌套序列化程序难以掌握。 我是在正确的轨道上,还是有更理想的结构可以更好地工作?非常感谢任何帮助!

【问题讨论】:

  • 您遇到了什么错误?
  • “city_id”列中的空值违反非空约束。我相信这是因为 subregion 没有城市(这是有意的,因为它应该从创建的 City 实例中获取此值)。
  • 检查我的答案@cmasri。

标签: python json django serialization django-rest-framework


【解决方案1】:

您的Subregion 模型有一个city 字段,它是外键并且不能为空。你的create 方法应该是这样的。

def create(self, validated_data):
    city_data = validated_data.pop('city', None)
    subregion_data = validated_data.pop('subregion', None)
    if city_data:
        city = City.objects.get_or_create(**city_data)[0]
    subregion = None
    if subregion_data:
        # Add city in Subregion data
        subregion_data.update({'city': city})
        subregion = Subregion.objects.get_or_create(**subregion_data)[0]

    code_log = CodeLog(
        code=validated_data.get('code'),
        city=city,
        subregion=subregion
    )
    code_log.save()
    return code_log

【讨论】:

    猜你喜欢
    • 2018-07-06
    • 2021-09-22
    • 2016-11-21
    • 2018-06-04
    • 2018-10-26
    • 2015-04-17
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多