简体   繁体   English

Django 将字段从序列化程序传递到 model.save(),这在 model 中不存在

[英]Django pass field from serializer to model.save() that is not present in the model

I need to pass fields that are present in serializer, but not present in model to model save method (I have complicated saving logic and I want to make some decisions in object creation based on these fields).我需要将序列化程序中存在但 model 中不存在的字段传递给 model 保存方法(我有复杂的保存逻辑,我想根据这些字段在 object 创建中做出一些决定)。 How can I do that?我怎样才能做到这一点? I tried to add non_db_field = property to model, but I still get error MyModel() got an unexpected keyword argument 'negative_amount'我尝试将non_db_field = property添加到 model,但我仍然收到错误MyModel() got an unexpected keyword argument 'negative_amount'

Let's say my model is假设我的 model 是

class MyModel(AbstractModel):
    field1 = models.DateTimeField()
    field2 = models.BigIntegerField()

My serializer is我的序列化器是

class MyModelSerializer(AbstractSerializer):
    field3 = serializers.BooleanField(required=False)

    class Meta(AbstractSerializer.Meta):
        model = MyModel
        fields = '__all__'

And my viewset is我的观点是

class MyModelViewSet(AbstractViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

You should handle this behavior in serializer.save method, for example, you can pop it from validated_data like that:您应该在serializer.save方法中处理此行为,例如,您可以像这样从validated_data中弹出它:

    def save(self, **kwargs):
        self.validated_data.pop("negative_amount")

        return super().save(**kwargs)

You can use fields=['field1', 'field2', 'field3'] in serializer instead of fields='__all__' .您可以在序列化程序中使用fields=['field1', 'field2', 'field3']而不是fields='__all__'

I found a solution based partly on Sharpek's answer and partly based on this answer:我找到了一个部分基于 Sharpek 的答案和部分基于这个答案的解决方案:

In serializer I override save method:序列化程序中,我覆盖了保存方法:

    def save(self, **kwargs):
        if 'field3' in self.validated_data:
            kwargs['field3'] = self.validated_data.pop('field3')
        return super().save(**kwargs)

In models I override init method and define field:模型中,我覆盖init方法并定义字段:

    field3 = None
    def __init__(self, *args, **kwargs):
        if 'field3' in kwargs:
            self.field3 = kwargs.pop('field3')
        super(Reading, self).__init__(*args, **kwargs)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM