什么是外键关系中drf序列化器的最佳实践

时间:2018-03-29 04:40:28

标签: python django django-rest-framework

我有两个模型类

class Parent(models.Model):
    sha256 = models.CharField(max_length=64)

class Child(models.Model):
    parent = models.ForeignKey(Parent, related_name="children")
    a = models.CharField()
    b = models.CharField()

我会请求以下内容:

(我想在找到与sha256对应的父类后保存子类)

{"sha256": "ABC....", "a": "test", "b": "test"}

如何覆盖验证和创建功能 以及如何写视图?

我想:

class ChildSerializer(serializer.ModelSerializer):

    def create(self, validated_data):
        sha256 = vadliated_data.pop('sha256')
        parent = Parent.objects.filter(sha256=sha256).first()
        if not parent:
            raise serializer.ValidationError('....')

        return Child.objects.create(**validated_data, parent=parent)

    class Meta:
         model = Child
         fields = ('sha256', 'a', 'b')

但它没有正常工作......最好的方法是什么?

这是我的观点(功能观点)

@api_view(['POST'])
def test(request):
    serializer = ChildSerializer(data=request.data)
    if serialzier.is_valid(raise_exception=True)
        serializer.save()
    return Response('...')

1 个答案:

答案 0 :(得分:1)

试试这个:

  

your_app - > models.py:

TYPE_CHOICES = (
    ('sha256', 'SHA256'),
    ('md5', 'MD5'),
)
class Parent(models.Model):
    type = models.CharField(
        choices=TYPE_CHOICES, default='sha256', max_length=64
    )
  

your_app - > serializers.py:

from your_app.models import TYPE_CHOICES

class ParentSerializer(serializers.ModelSerializer):
    type = serializers.ChoiceField(choices=TYPE_CHOICES, default='sha256')

    class Meta:
        model = Parent
        fields = (
            'type',
        )

class ChildSerializer(serializers.ModelSerializer):
    parent = ParentSerializer(required=True)
    a = serializers.CharField(required=True)
    b = serializers.CharField(required=True)

    def create(self, validated_data):
        type = validated_data.pop('type')

        try:
            parent = Parent.objects.get(type=type)
        except:
            raise serializers.ValidationError('...')

        return Child.objects.create(
            parent=parent,
            **validated_data
        )

    class Meta:
         model = Child
         fields = (
            'parent', 'a', 'b'
        )