在mixin中的Django rest framework modelserializer(只写&读写)中添加添加字段
我想为Modelserializer中的其他字段创建一个mixin。 请参考下面的代码在mixin中的Django rest framework modelserializer(只写&读写)中添加添加字段,django,django-rest-framework,Django,Django Rest Framework,我想为Modelserializer中的其他字段创建一个mixin。 请参考下面的代码 class AdditionalFieldsMixin(object): additional_fields = dict() def __init__(self, *args, **kwargs): super(AdditionalFieldsMixin, self).__init__(*args, **kwargs) for field_name, fie
class AdditionalFieldsMixin(object):
additional_fields = dict()
def __init__(self, *args, **kwargs):
super(AdditionalFieldsMixin, self).__init__(*args, **kwargs)
for field_name, field_instance in self.additional_fields.items():
self.fields[field_name] = field_instance
print(self.fields)
def additional_field_before_create(self, additional_field_data):
pass
def additional_field_after_create(self, additional_field_data, instance):
pass
def additional_field_before_update(self, additional_field_data):
pass
def additional_field_after_update(self, additional_field_data, instance):
pass
def create(self, validated_data):
additional_field_data = {}
for additional_field in self.additional_fields.keys():
additional_field_data[additional_field] = validated_data.pop(additional_field, None)
self.additional_field_before_create(additional_field_data)
instance = super(AdditionalFieldsMixin, self).create(validated_data)
self.additional_field_after_create(additional_field_data, instance)
return instance
def update(self, instance, validated_data):
additional_field_data = {}
for additional_field in self.additional_fields.keys():
additional_field_data[additional_field] = validated_data.pop(additional_field, None)
self.additional_field_before_update(additional_field_data)
instance = super(AdditionalFieldsMixin, self).update(instance, validated_data)
self.additional_field_after_update(additional_field_data, instance)
return instance
在主课堂上,我宣布
additional_fields = dict(
reference=CharField(write_only=True, allow_blank=True, allow_null=True, default=None),
)
但在列表模式下检索数据时,它会给我一个错误
AssertionError: It is redundant to specify `source='reference'` on field 'CharField' in serializer 'MySerializer', because it is the same as the field name. Remove the `source` keyword argument.
为什么会这样?
我还注意到,在第一次启动runserver之后,它不会给出那个错误,但如果我再次查询,它会给出第二次错误,以此类推
还有一个一般性问题
在seialiser mixin类中添加字段的正确方法是什么?
i、 e self.fields[field\u name]=field\u实例是正确的方法吗?您可以这样做,因为如果您使用Modelializer,您不能请求
class Name(serializers.Serializer):
name = serializers.CharField(required=True)
...
def create(self, validated_data):
...
def update(self, instance, validated_data):
...
可以这样做,因为如果使用Modelializer,则无法请求
class Name(serializers.Serializer):
name = serializers.CharField(required=True)
...
def create(self, validated_data):
...
def update(self, instance, validated_data):
...
Modelserializer上的额外读写字段 额外的读和写字段必须从模型实例派生,以便您可以在模型上添加
@property
或def reference
,并在序列化程序中将字段声明为
reference = CharField(source='reference')
reference = CharField(write_only=True)
并从覆盖modelserializer的创建更新的验证数据中弹出字段数据
简而言之,在直接代码中很难实现额外的读写字段,但这是可能的。
Modelserializer上的额外只读字段
将SerializerMethodField
、ReadOnlyField
与source
参数一起使用,或与上述代码类似的readonly=True
参数一起使用。e、 g
reference = CharField(source='reference', read_only=True)
Modelserializer上的额外只写字段(必选答案)
将mainserializer上的字段写入为
reference = CharField(source='reference')
reference = CharField(write_only=True)
如果没有问题,该字段将显示在创建
和更新
中的验证数据中
覆盖它们,弹出字段,做你想做的事情,用新的验证数据调用super()
按照问题中的要求进行混音(对于只写字段)
事实证明,您可以重写序列化程序的to_internal_value
方法并向其添加字段。序列化程序保存数据(创建、更新)时会调用to_internal_值
,因此您可以按如下方式覆盖它
def to_internal_value(self, data):
for field_name, field_instance in self.additional_write_only_fields.items():
self.fields[field_name] = field_instance
return super(AdditionalWriteOnlyFieldsMixin, self).to_internal_value(data)
class AdditionalWriteOnlyFieldsMixin(object):
additional_write_only_fields = dict()
def to_internal_value(self, data):
for field_name, field_instance in self.additional_write_only_fields.items():
self.fields[field_name] = field_instance
return super(AdditionalWriteOnlyFieldsMixin, self).to_internal_value(data)
def additional_fields_before_create(self, additional_data):
pass
def additional_fields_after_create(self, additional_data, instance):
pass
def additional_fields_before_update(self, additional_data):
pass
def additional_fields_after_update(self, additional_data, instance):
pass
def create(self, validated_data):
additional_data = {key: validated_data.pop(key, None) for key in self.additional_write_only_fields.keys()}
self.additional_fields_before_create(additional_data)
instance = super(AdditionalWriteOnlyFieldsMixin, self).create(validated_data)
self.additional_fields_after_create(additional_data, instance)
return instance
def update(self, instance, validated_data):
additional_data = {key: validated_data.pop(key, None) for key in self.additional_write_only_fields.keys()}
self.additional_fields_before_update(additional_data)
instance = super(AdditionalWriteOnlyFieldsMixin, self).update(instance, validated_data)
self.additional_fields_after_update(additional_data, instance)
return instance
这将解决向模型序列化程序添加许多只写字段的问题。这就是我创建mixin的原因,如下所示
def to_internal_value(self, data):
for field_name, field_instance in self.additional_write_only_fields.items():
self.fields[field_name] = field_instance
return super(AdditionalWriteOnlyFieldsMixin, self).to_internal_value(data)
class AdditionalWriteOnlyFieldsMixin(object):
additional_write_only_fields = dict()
def to_internal_value(self, data):
for field_name, field_instance in self.additional_write_only_fields.items():
self.fields[field_name] = field_instance
return super(AdditionalWriteOnlyFieldsMixin, self).to_internal_value(data)
def additional_fields_before_create(self, additional_data):
pass
def additional_fields_after_create(self, additional_data, instance):
pass
def additional_fields_before_update(self, additional_data):
pass
def additional_fields_after_update(self, additional_data, instance):
pass
def create(self, validated_data):
additional_data = {key: validated_data.pop(key, None) for key in self.additional_write_only_fields.keys()}
self.additional_fields_before_create(additional_data)
instance = super(AdditionalWriteOnlyFieldsMixin, self).create(validated_data)
self.additional_fields_after_create(additional_data, instance)
return instance
def update(self, instance, validated_data):
additional_data = {key: validated_data.pop(key, None) for key in self.additional_write_only_fields.keys()}
self.additional_fields_before_update(additional_data)
instance = super(AdditionalWriteOnlyFieldsMixin, self).update(instance, validated_data)
self.additional_fields_after_update(additional_data, instance)
return instance
因此,在modelserializer类中包含mixin,并将附加的\u只写\u字段
声明为dict,将key作为字段名,将value作为字段实例,并重写附加的\u字段*
函数以实现所需的功能,例如
class MySerializer(AdditionalWriteOnlyFieldsMixin, ModelSerializer):
additional_write_only_fields = dict(
reference=CharField(write_only=True, allow_blank=True, allow_null=True, default=None),
)
def additional_fields_after_create(self, additional_data, instance):
print(additional_data)
class Meta:
model=MyModel
fields='__all__'
附加注释
您还可以重写序列化程序的to_表示法
方法,以添加只读字段,或者将to_表示法
和to_内部值
组合起来,以创建额外的读写字段!。但是我离开这个工作去另一个答案,呃
参考资料
-
-
Modelserializer上的额外读写字段
额外的读和写字段必须从模型实例派生,以便您可以在模型上添加@property
或def reference
,并在序列化程序中将字段声明为
reference = CharField(source='reference')
reference = CharField(write_only=True)
并从覆盖modelserializer的创建更新的验证数据中弹出字段数据
简而言之,在直接代码中很难实现额外的读写字段,但这是可能的。
Modelserializer上的额外只读字段
将SerializerMethodField
、ReadOnlyField
与source
参数一起使用,或与上述代码类似的readonly=True
参数一起使用。e、 g
reference = CharField(source='reference', read_only=True)
Modelserializer上的额外只写字段(必选答案)
将mainserializer上的字段写入为
reference = CharField(source='reference')
reference = CharField(write_only=True)
如果没有问题,该字段将显示在创建
和更新
中的验证数据中
覆盖它们,弹出字段,做你想做的事情,用新的验证数据调用super()
按照问题中的要求进行混音(对于只写字段)
事实证明,您可以重写序列化程序的to_internal_value
方法并向其添加字段。序列化程序保存数据(创建、更新)时会调用to_internal_值
,因此您可以按如下方式覆盖它
def to_internal_value(self, data):
for field_name, field_instance in self.additional_write_only_fields.items():
self.fields[field_name] = field_instance
return super(AdditionalWriteOnlyFieldsMixin, self).to_internal_value(data)
class AdditionalWriteOnlyFieldsMixin(object):
additional_write_only_fields = dict()
def to_internal_value(self, data):
for field_name, field_instance in self.additional_write_only_fields.items():
self.fields[field_name] = field_instance
return super(AdditionalWriteOnlyFieldsMixin, self).to_internal_value(data)
def additional_fields_before_create(self, additional_data):
pass
def additional_fields_after_create(self, additional_data, instance):
pass
def additional_fields_before_update(self, additional_data):
pass
def additional_fields_after_update(self, additional_data, instance):
pass
def create(self, validated_data):
additional_data = {key: validated_data.pop(key, None) for key in self.additional_write_only_fields.keys()}
self.additional_fields_before_create(additional_data)
instance = super(AdditionalWriteOnlyFieldsMixin, self).create(validated_data)
self.additional_fields_after_create(additional_data, instance)
return instance
def update(self, instance, validated_data):
additional_data = {key: validated_data.pop(key, None) for key in self.additional_write_only_fields.keys()}
self.additional_fields_before_update(additional_data)
instance = super(AdditionalWriteOnlyFieldsMixin, self).update(instance, validated_data)
self.additional_fields_after_update(additional_data, instance)
return instance
这将解决向模型序列化程序添加许多只写字段的问题。这就是我创建mixin的原因,如下所示
def to_internal_value(self, data):
for field_name, field_instance in self.additional_write_only_fields.items():
self.fields[field_name] = field_instance
return super(AdditionalWriteOnlyFieldsMixin, self).to_internal_value(data)
class AdditionalWriteOnlyFieldsMixin(object):
additional_write_only_fields = dict()
def to_internal_value(self, data):
for field_name, field_instance in self.additional_write_only_fields.items():
self.fields[field_name] = field_instance
return super(AdditionalWriteOnlyFieldsMixin, self).to_internal_value(data)
def additional_fields_before_create(self, additional_data):
pass
def additional_fields_after_create(self, additional_data, instance):
pass
def additional_fields_before_update(self, additional_data):
pass
def additional_fields_after_update(self, additional_data, instance):
pass
def create(self, validated_data):
additional_data = {key: validated_data.pop(key, None) for key in self.additional_write_only_fields.keys()}
self.additional_fields_before_create(additional_data)
instance = super(AdditionalWriteOnlyFieldsMixin, self).create(validated_data)
self.additional_fields_after_create(additional_data, instance)
return instance
def update(self, instance, validated_data):
additional_data = {key: validated_data.pop(key, None) for key in self.additional_write_only_fields.keys()}
self.additional_fields_before_update(additional_data)
instance = super(AdditionalWriteOnlyFieldsMixin, self).update(instance, validated_data)
self.additional_fields_after_update(additional_data, instance)
return instance
因此,在modelserializer类中包含mixin,并将附加的\u只写\u字段
声明为dict,将key作为字段名,将value作为字段实例,并重写附加的\u字段*
函数以实现所需的功能,例如
class MySerializer(AdditionalWriteOnlyFieldsMixin, ModelSerializer):
additional_write_only_fields = dict(
reference=CharField(write_only=True, allow_blank=True, allow_null=True, default=None),
)
def additional_fields_after_create(self, additional_data, instance):
print(additional_data)
class Meta:
model=MyModel
fields='__all__'
附加注释
您还可以重写序列化程序的to_表示法
方法,以添加只读字段,或者将to_表示法
和to_内部值
组合起来,以创建额外的读写字段!。但是我离开这个工作去另一个答案,呃
参考资料
-
-