ModelSerializer с использованием свойства модели

101

Я пытаюсь сериализовать модель, содержащую поле свойств, которое я также хочу сериализовать.

models.py:

class MyModel(models.Model):
    name = models.CharField(max_length=100)
    slug = models.AutoSlugField(populate_from='name')

    @property
    def ext_link(self):
        return "/".join([settings.EXT_BASE_URL, self.slug])

serializers.py:

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')

При попытке перейти к соответствующему URL-адресу я получаю исключение сериализатора (KeyError) для ext_linkсвойства.

Как я могу сериализовать ext_linkсвойство?

Сандер Смитс
источник

Ответы:

138

Поскольку это не поле модели, его необходимо явно добавить в класс сериализатора.

class MyModelSerializer(serializers.ModelSerializer):
    ext_link = serializers.Field()

    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')
Том Кристи
источник
5
Одно примечание : список полей в Meta необязателен. Если вы опуститеfields, в приведенном выше примере вы получите всеMyModelполя плюсext_linkсериализованные данные. И это действительно круто для сложных моделей! РЕДАКТИРОВАТЬ : По крайней мере, это верно дляdjangorestframework==2.3.14.
e.thompsy
Для меня использование serializers.Field выдало ошибку. "serializers.ReadOnlyField" работает, если to_presentation не определено и представление доступно только для чтения.
Шашанк Сингла
15
Я использую 3.3.x, и простого добавления свойств в поля недостаточно. Мне еще нужно явно добавить через ext_link = serializers.ReadOnlyField ().
jarmod
4
используя DRF 3.4.6 на Python 3.5.1 и Django 1.10, добавление полей работает нормально.
Вайбхав Мишра
9
Примечание: при использовании fields = "__all__"мне также пришлось добавить, myfield = serializers.ReadOnlyField()как указано в jarmod, используя версию 3.7.7
Роберт Таунли
22

как @Robert Townleyкомментарий, эта работа с версией 3.8.2:

class MyModelSerializer(serializers.ModelSerializer):
    ext_link = serializers.ReadOnlyField()

    class Meta:
        model = MyModel
        fields = "__all__"
Suhailvs
источник