ModelSerializer з використанням властивості model


95

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

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власність?

Відповіді:


134

Оскільки це не поле моделі, його потрібно явно додати до класу серіалізатора

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

    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')

5
Одна примітка : Список полів у Meta не є обов’язковим. Якщо пропуститиfields, у наведеному вище прикладі ви отримаєте всіMyModelполя плюсext_linkу серіалізованих даних. І це дійсно приголомшливо для складних моделей! EDIT : Принаймні, це справедливо дляdjangorestframework==2.3.14.
e.thompsy

Для мене використання серіалізаторів. Поле дало помилку. "serializers.ReadOnlyField" працює, якщо to_representation не визначено і подання доступне лише для читання.
Шашанк Сінгла

13
Я використовую 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
Роберт Таунлі

20

як @Robert Townleyкоментар, ця робота з версією 3.8.2:

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

    class Meta:
        model = MyModel
        fields = "__all__"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.