Django Rest Framework - Как добавить настраиваемое поле в ModelSerializer
Я создал ModelSerializer
и хочу добавить настраиваемое поле, которое не является частью моей модели.
Я нашел описание для добавления дополнительных полей здесь и попробовал следующее:
customField = CharField(source='my_field')
Когда я добавляю это поле и вызываю свою функцию validate()
, это поле не является частью диктата attr
. attr
содержит все указанные поля модели, кроме дополнительных полей. Не могу ли я получить доступ к этому полю в моей перезаписанной проверке?
Когда я добавляю это поле в список полей следующим образом:
class Meta:
model = Account
fields = ('myfield1', 'myfield2', 'customField')
затем я получаю сообщение об ошибке, потому что customField
не является частью моей модели - что правильно, потому что я хочу добавить его только для этого сериализатора.
Есть ли способ добавить пользовательское поле?
Ответы
Ответ 1
Вы поступаете правильно, за исключением того, что CharField
(и другие введенные поля) предназначены для записываемых полей.
В этом случае вам просто нужно простое поле только для чтения, поэтому вместо этого просто используйте:
customField = Field(source='get_absolute_url')
Ответ 2
На самом деле есть решение, не касающееся всей модели. Вы можете использовать SerializerMethodField
, которые позволяют подключать любой метод к вашему сериализатору.
class FooSerializer(ModelSerializer):
foo = serializers.SerializerMethodField()
def get_foo(self, obj):
return "Foo id: %i" % obj.pk
Ответ 3
... для ясности, если у вас есть метод модели, определенный следующим образом:
class MyModel(models.Model):
...
def model_method(self):
return "some_calculated_result"
Вы можете добавить результат вызова указанного метода к вашему сериализатору следующим образом:
class MyModelSerializer(serializers.ModelSerializer):
model_method_field = serializers.CharField(source='model_method')
p.s. Поскольку пользовательское поле на самом деле не является полем в вашей модели, вы, как правило, хотите сделать его доступным только для чтения, например:
class Meta:
model = MyModel
read_only_fields = (
'model_method_field',
)
Ответ 4
здесь ответьте на свой вопрос.
вы должны добавить в свою учетную запись модели:
@property
def my_field(self):
return None
теперь вы можете использовать:
customField = CharField(source='my_field')
источник: fooobar.com/questions/64148/...
Ответ 5
Чтобы показать 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')
Ответ 6
В последней версии Django Rest Framework вам необходимо создать метод в вашей модели с именем поля, которое вы хотите добавить.
class Foo(models.Model):
. . .
def foo(self):
return 'stuff'
. . .
class FooSerializer(ModelSerializer):
foo = serializers.ReadOnlyField()
class Meta:
model = Foo
fields = ('foo',)
Ответ 7
Я искал решение для добавления настраиваемого поля для записи в сериализатор модели. Я нашел этот, который не был рассмотрен в ответах на этот вопрос.
Похоже, вам действительно нужно написать свой собственный простой сериализатор.
class PassThroughSerializer(serializers.Serializer):
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
, но вы хотите игнорировать его валидаторы.