Я создал ModelSerializer
и хочу добавить настраиваемое поле, которое не является частью моей модели.
Я нашел описание для добавления дополнительных полей сюда и попробовал следующее:
customField = CharField(source='my_field')
Когда я добавляю это поле и вызываю свою validate()
функцию, это поле не является частью attr
dict. attr
содержит все указанные поля модели, кроме дополнительных полей. Значит, я не могу получить доступ к этому полю в моей перезаписанной проверке, можно?
Когда я добавляю это поле в список полей следующим образом:
class Meta:
model = Account
fields = ('myfield1', 'myfield2', 'customField')
то я получаю сообщение об ошибке, потому что customField
не является частью моей модели - что правильно, потому что я хочу добавить его только для этого сериализатора.
Есть ли способ добавить настраиваемое поле?
Ответы:
Вы поступаете правильно, за исключением того, что
CharField
(и другие типизированные поля) предназначены для полей с возможностью записи.В этом случае вам просто нужно простое поле только для чтения, поэтому вместо этого просто используйте:
customField = Field(source='get_absolute_url')
источник
.validate()
метод для удаления атрибута. См .: django-rest-framework.org/api-guide/serializers.html#validation. Это сделает то, что вам нужно, хотя я не совсем понимаю вариант использования или почему вам нужно поле с возможностью записи , привязанное к свойство только для чтенияget_absolute_url
?get_absolute_url
я просто скопировал и вставил его из документации. Мне просто нужно обычное поле с возможностью записи, к которому я могу получить доступ вvalidate()
. Я просто догадался, что мне понадобитсяsource
атрибут ...На самом деле есть решение, вообще не касаясь модели. Вы можете использовать,
SerializerMethodField
который позволяет вам подключить любой метод к вашему сериализатору.class FooSerializer(ModelSerializer): foo = serializers.SerializerMethodField() def get_foo(self, obj): return "Foo id: %i" % obj.pk
источник
SerializerMethodField
с возможностью записи, а это не так... для ясности, если у вас есть метод модели, определенный следующим образом:
class MyModel(models.Model): ... def model_method(self): return "some_calculated_result"
Вы можете добавить результат вызова указанного метода в свой сериализатор следующим образом:
class MyModelSerializer(serializers.ModelSerializer): model_method_field = serializers.CharField(source='model_method')
ps Поскольку настраиваемое поле на самом деле не является полем в вашей модели, вы обычно хотите сделать его доступным только для чтения, например:
class Meta: model = MyModel read_only_fields = ( 'model_method_field', )
источник
perform_create(self, serializer)
,perform_update(self, serializer)
,perform_destroy(self, instance)
.вот ответ на ваш вопрос. вы должны добавить в свою модельную учетную запись:
@property def my_field(self): return None
теперь вы можете использовать:
customField = CharField(source='my_field')
источник: https://stackoverflow.com/a/18396622/3220916
источник
Чтобы показать
self.author.full_name
, у меня ошибкаField
. Он работал сReadOnlyField
:class CommentSerializer(serializers.HyperlinkedModelSerializer): author_name = ReadOnlyField(source="author.full_name") class Meta: model = Comment fields = ('url', 'content', 'author_name', 'author')
источник
В последней версии Django Rest Framework вам необходимо создать метод в своей модели с именем поля, которое вы хотите добавить.
class Foo(models.Model): . . . def foo(self): return 'stuff' . . . class FooSerializer(ModelSerializer): foo = serializers.ReadOnlyField() class Meta: model = Foo fields = ('foo',)
источник
Я искал решение для добавления настраиваемого поля с возможностью записи в сериализатор модели. Я нашел этот, который не был рассмотрен в ответах на этот вопрос.
Похоже, вам действительно нужно написать собственный простой сериализатор.
class PassThroughSerializer(serializers.Field): def to_representation(self, instance): # This function is for the direction: Instance -> Dict # If you only need this, use a ReadOnlyField, or SerializerField return None def to_internal_value(self, data): # This function is for the direction: Dict -> Instance # Here you can manipulate the data if you need to. return data
Теперь вы можете использовать этот сериализатор для добавления настраиваемых полей в ModelSerializer.
class MyModelSerializer(serializers.ModelSerializer) my_custom_field = PassThroughSerializer() def create(self, validated_data): # now the key 'my_custom_field' is available in validated_data ... return instance
Это также работает, если у модели
MyModel
действительно есть свойство с именем,my_custom_field
но вы хотите игнорировать его валидаторы.источник
MyModel
экземпляре.Прочитав здесь все ответы, я пришел к выводу, что это невозможно сделать чисто. Вы должны играть грязные и делать что - то hadkish как создать write_only поле , а затем переопределить
validate
иto_representation
методы. Вот что сработало для меня:class FooSerializer(ModelSerializer): foo = CharField(write_only=True) class Meta: model = Foo fields = ["foo", ...] def validate(self, data): foo = data.pop("foo", None) # Do what you want with your value return super().validate(data) def to_representation(self, instance): data = super().to_representation(instance) data["foo"] = whatever_you_want return data
источник