序列化程序上的 Django verbose_name 属性

Rod*_*vid 6 python django django-rest-framework

我正在为 angular cli 使用 django rest 框架构建 API 后端,但我不知道如何访问 verbose_name 的模型字段属性以对其进行序列化。这是我的代码:

models.py
class MyModel(model.Models):
    myField = models.CharField(verbose_name='My Verbose Name')
    # Here I have other 30 fields
Run Code Online (Sandbox Code Playgroud)

这是此模型的序列化程序

serializers.py
class MyModelSerializer(ModelSerializer):  
    myField = SerializerMethodField()

    def get_myField(self, obj):
        field = next(f for f in obj._meta.fields if f.name == 'myField')
        myField=  {
            'verbose_name': field.verbose_name.title(),
            'value': obj.myField
            }
        return myField
    # Do I Have to repeat this function for every field on my Model in order to have verbose-name ??

    class Meta:
        model = MyModel
        fields = ['nominativo' ]
Run Code Online (Sandbox Code Playgroud)

我的观点是:

class MyModelListAPIView(ListAPIView):
    queryset = Archivio.objects.all()
    serializer_class = MyModelSerializer
Run Code Online (Sandbox Code Playgroud)

我的输出就像我想要的那样:

[
    {
    "myField":
        {
         "verbose_name":"My Verbose Name",
         "value":"My Field value"
         }
    }
]
Run Code Online (Sandbox Code Playgroud)

但这对只有几个字段没问题。在我的情况下,我需要像这样的输出,其中包含我的模型的 30 个字段。有没有更好的解决方案而不是get_field在我的ModelSerializer班级上创建 30 个函数?

mar*_*xin 6

我认为使用字段本身(将表示更改为对象)可能不是实现您需要的最佳方式(当然不是最简单的)。

相反,我会尝试定义自动生成“标签”字段的 ModelSerializer,例如(基本实现):

from rest_framework import serializers
from rest_framework.fields import SerializerMethodField


class MyModelSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        super(MyModelSerializer, self).__init__(*args, **kwargs)

        if 'labels' in self.fields:
            raise RuntimeError(
                'You cant have labels field defined '
                'while using MyModelSerializer'
            )

        self.fields['labels'] = SerializerMethodField()

    def get_labels(self, *args):
        labels = {}

        for field in self.Meta.model._meta.get_fields():
            if field.name in self.fields:
                labels[field.name] = field.verbose_name

        return labels
Run Code Online (Sandbox Code Playgroud)

然后,如果您使用 MyModelSerializer 而不是 serializers.ModelSerializer,您将得到如下输出:

{
  'name': 'Test',
  'email': 'test@test.com',
  'labels': {
     'name': 'Full name',
     'email': 'Email address'
  }
}
Run Code Online (Sandbox Code Playgroud)

这样,django rest 框架生成的所有字段的逻辑保持不变,并且您有另一个只读字段。漂亮干净。