DRF外键序列化

时间:2019-10-21 17:27:25

标签: django django-rest-framework

我无法使用Foreignkey字段保存模型。

感谢“ azudo”问题的解决。下面的解决方案

例如,我有简单的模型:

class User(AbstractUser):
    class Meta:
        pass

    email_validator = EmailValidator()
    username = models.CharField('Name', max_length=150, )
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    email = models.EmailField('Email', blank=True, unique=True, validators=[email_validator], )
    ...

class Package(models.Model):

    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='packages')
    description = models.CharField('Description', max_length=256, default='description')
    weight = models.CharField('weight', max_length=256, default='weight')
    ...

查看(确保用户在请求中):

@api_view(["POST"])
def test(request):
    data = request.data
    data['user'] = User.objects.get(id=request.user.id)
    serializer = PackageSerializer(data=data)
    if serializer.is_valid():
        serializer.save()
        return JsonResponse(serializer.data)
    else:
        return JsonResponse(serializer.errors)

我的序列化器:

class UserSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'


class PackageSerializer(ModelSerializer):

    class Meta:
        model = Package
        fields = (
            'user', 'description', 'weight', 'dimensions', 'estimated_shipping_cost', 'deliver_to_date')

    def to_representation(self, instance):
        self.fields['user'] = UserSerializer(many=False, read_only=True)
        self.fields['where_from'] = LocationSerializer(many=False, read_only=True)
        self.fields['destination'] = LocationSerializer(many=False, read_only=True)
        return super().to_representation(instance)

    def create(self, validated_data):
        user = User.objects.get(validated_data.pop('user'))
        package = Package.objects.create(user=user, **validated_data)
        return package

请求中的json:

{
    "description": "Some package",
    "weight": "12",
}

因此,我在数据库中拥有用户,并希望为他创建软件包。但是在create中被覆盖的PackageSerializer中,validated_data没有user。请解释我在做什么错。

django和drf的版本:

django==2.2.4
djangorestframework==3.10.2   

解决方案:

序列化器:

class PackageSerializer(ModelSerializer):
    user = UserSerializer(many=False, read_only=True)

    class Meta:
        model = Package
        fields = (
            'user', 'description', 'weight', 'dimensions', 'estimated_shipping_cost', 'deliver_to_date')

    def create(self, validated_data):
        user = User.objects.get(validated_data.pop('user'))
        package = Package.objects.create(user=user)
        return package

查看:

@api_view(["POST"])
def create_package(request):
    data = request.data
    serializer = PackageSerializer(data=data)
    if serializer.is_valid():
        serializer.save(user=request.user)
        return JsonResponse(serializer.data)
    else:
        return JsonResponse(serializer.errors)

1 个答案:

答案 0 :(得分:1)

DRF将忽略包含的标记为只读的字段,因此调用方不能包含只读数据。如果要包括其他属性,只需将它们作为关键字args传递即可保存: https://www.django-rest-framework.org/api-guide/serializers/#passing-additional-attributes-to-save

例如

@api_view(["POST"])
def test(request):
    data = request.data
    serializer = PackageSerializer(data=data)
    if serializer.is_valid():
        serializer.save(user=request.user)
        return JsonResponse(serializer.data)
    else:
        return JsonResponse(serializer.errors)