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, но вы хотите игнорировать его валидаторы.