【问题标题】:How to get TextField to render in API Browser in DRF?如何让 TextField 在 DRF 的 API 浏览器中呈现?
【发布时间】:2019-05-20 14:51:59
【问题描述】:

使用 DRF,我有一个包含地址字段的用户模型,它是一个文本字段。当我在 API 浏览器中查看 UserList 端点时,地址如下所示:

"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,
    )

这是地址和电话字段的模型类:

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',
        )

地址和电话字段序列化器:

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": "admin@virticl.api",
"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>",

【问题讨论】:

  • 您可以添加您的视图以及序列化程序吗?]

标签: django django-rest-framework


【解决方案1】:

您的抽象模型 mixin 应该是 models.Model 子类:

class AddressPhoneModelMixin(models.Model):
    ...

您还需要按照用户模型的基类顺序将其放在左侧,因为继承是从右到左处理的:

class User(AddressPhoneModelMixin, AbstractUser):
    ...

注意:对于specify serializer fields,您可以使用fields = '__all__' 而不是单独列出它们。如果只是缺少一两个,您可以使用exclude

【讨论】:

  • 成功了。谢谢你。回复:对字段使用“all”,这不是需要排除任何字段的问题,而是添加一个。如果我指定“all”,我将如何添加不是实际数据库字段的“url”超链接字段?
  • __all__ 不引用数据库字段。它指的是序列化器字段。 ModelSerializer 将模型字段映射到序列化器字段,但这仅意味着您的序列化器字段就是您的所有模型字段加上您在序列化器中明确定义的任何内容。
  • 附带说明:我刚刚注意到您在序列化程序上定义了permission_classes,但这是一个视图属性。我认为它对序列化程序没有任何影响(除非您自己在某处使用它)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-02
  • 1970-01-01
  • 1970-01-01
  • 2016-01-14
  • 2022-07-22
  • 2018-09-04
  • 2019-06-19
相关资源
最近更新 更多