Как заставить TextField отображаться в браузере API в DRF?

Используя DRF, у меня есть модель пользователя, которая включает поле адреса, которое является текстовым полем. Когда я просматриваю конечную точку UserList в браузере API, адрес выглядит так:

"address": "<django.db.models.fields.TextField>",

Из документации я подумал, что мне нужно это в моем сериализаторе:

    address = serializers.CharField(
        max_length=1000,
        style = {'base_template': 'textarea.html'},
    )

... но это не решило проблему. То же самое происходит и с полями типа PhoneNumberField:

"phone_number": "<phonenumber_field.modelfields.PhoneNumberField>",

Я переопределил их в своем сериализаторе как CharField.

ОБНОВИТЬ:

Мои модели и сериализаторы немного сложнее, чем обычно, потому что я разбиваю поля «Адрес», «Страна» и три поля телефона на отдельные классы, чтобы их можно было включить в несколько разных моделей.

Мои пользовательские модели:

class User(AbstractUser, AddressPhoneModelMixin):
    objects = UserProfileManager()

    USERNAME_FIELD = 'email'

    type = models.CharField(
        max_length=25,
    )
    title = models.CharField(
        max_length=100,
        blank=True,
        null=True,
    )
    timezone = models.CharField(
        max_length=50,
    )
    birthdate = models.DateTimeField(
        blank=True,
        null=True,
    )
    is_verified = models.BooleanField(
        default=False,
    )
    email = models.EmailField(
        unique=True,
        db_index=True,
    )

Это класс модели для полей Address и Phone:

class AddressPhoneModelMixin(object):
    address = models.TextField(
        blank=True,
        null=True,
    )
    country = models.ForeignKey(
        Country,
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )
    phone_number = PhoneNumberField(
        blank=True,
        null=True,
    )
    mobile_number = PhoneNumberField(
        blank=True,
        null=True,
    )
    fax_number = PhoneNumberField(
        blank=True,
        null=True,
    )

    class Meta:
        abstract = True

Пользовательский сериализатор:

class UserSerializer(AddressPhoneSerializerMixin, serializers.ModelSerializer):

    permission_classes = (permissions.IsAuthenticated,)

    url = serializers.HyperlinkedIdentityField(view_name = "users:user-detail")

    class Meta:
        model = User
        fields = (
            'url',
            'id',
            'type',
            'username',
            'first_name',
            'last_name',
            'full_name',
            'email',
            'address',
            'country',
            'phone_number',
            'mobile_number',
            'fax_number',
            'is_superuser',
            'is_staff',
            'is_active',
            'is_verified',
            'date_joined',
            'last_login',
        )

Сериализатор полей Address и Phone:

class AddressPhoneSerializerMixin(serializers.Serializer):

    address = serializers.CharField(
        max_length=1000,
        style = {'base_template': 'textarea.html'},
    )
    country = serializers.HyperlinkedIdentityField(
        view_name='countries:country-detail'
    )
    phone_number = serializers.CharField(
        max_length=31,
    )
    mobile_number = serializers.CharField(
        max_length=31,
    )
    fax_number = serializers.CharField(
        max_length=31,
    )

    class Meta:
        abstract = True

И, наконец, Пользователь просматривает:

class UserList(ListCreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = User.objects.all()
    serializer_class = UserSerializer

class UserDetail(RetrieveUpdateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = User.objects.all()
    serializer_class = UserSerializer

Я включу пример из браузера API, который включает все рассматриваемые поля. Обратите внимание, что Country отображается так, как ожидалось.

"email": "[email protected]",
"address": "<django.db.models.fields.TextField>",
"country": "http://virticl.api/countries/1/",
"phone_number": "<phonenumber_field.modelfields.PhoneNumberField>",
"mobile_number": "<phonenumber_field.modelfields.PhoneNumberField>",
"fax_number": "<phonenumber_field.modelfields.PhoneNumberField>",

Вы можете добавить свои представления, а также сериализатор?]

JPG 20.05.2019 16:57
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
536
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш миксин абстрактной модели должен быть подклассом models.Model:

class AddressPhoneModelMixin(models.Model):
    ...

Вам также нужно поместить его слева в порядке базовых классов для вашей пользовательской модели, поскольку наследование обрабатывается справа налево:

class User(AddressPhoneModelMixin, AbstractUser):
    ...

ПРИМЕЧАНИЕ: для указать поля сериализатора вы можете использовать fields = '__all__' вместо того, чтобы перечислять их по отдельности. Если не хватает только одного или двух, вы можете вместо этого использовать exclude.

Это помогло. Спасибо. Re: используя «все» для полей, это не вопрос необходимости исключения каких-либо полей, а скорее добавление одного. Если я укажу «все», как мне добавить поле с гиперссылкой «url», которое не является фактическим полем базы данных?

ExTexan 21.05.2019 10:18
__all__ не относится к полям базы данных. Это относится к полям сериализатора. ModelSerializer сопоставляет поля модели с полями сериализатора, но это просто означает, что ваши поля сериализатора — это все поля вашей модели плюс все, что вы явно определяете в сериализаторе.
RishiG 21.05.2019 15:31

В качестве примечания: я только что заметил, что вы определили permission_classes в своем сериализаторе, но это атрибут представления. Я не думаю, что это имеет какой-либо эффект в сериализаторе (если вы не используете его где-то самостоятельно).

RishiG 21.05.2019 15:33

Другие вопросы по теме