我正在使用django rest框架为angular cli构建一个API后端,我不知道如何访问verbose_name的模型字段属性以便序列化它。这是我的代码:
models.py
class MyModel(model.Models):
myField = models.CharField(verbose_name='My Verbose Name')
# Here I have other 30 fields
这是此型号的序列化器
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' ]
我的观点是:
class MyModelListAPIView(ListAPIView):
queryset = Archivio.objects.all()
serializer_class = MyModelSerializer
我的输出就像我的愿望,就像这样:
[
{
"myField":
{
"verbose_name":"My Verbose Name",
"value":"My Field value"
}
}
]
但只有少数几个字段就可以了。在我的情况下,我需要有一个这样的输出与我的模型的30个字段。有没有更好的解决方案,而不是在我的get_field
类上制作30个ModelSerializer
函数?
答案 0 :(得分:3)
我认为使用字段本身(将表示更改为对象)可能不是实现所需内容的最佳方式(当然不是最简单的方法)。
相反,我会尝试定义我的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
然后,如果您使用MyModelSerializer而不是serializers.ModelSerializer,您将获得如下输出:
{
'name': 'Test',
'email': 'test@test.com',
'labels': {
'name': 'Full name',
'email': 'Email address'
}
}
这样,django rest框架生成的所有字段的逻辑保持不变,并且你有一个只读字段。很干净。
答案 1 :(得分:2)
您必须覆盖.to_representation
课程的ModelSerializer
Docs
Source code
你想要这样的东西(修改后的原始source) -
from rest_framework import serializers
from rest_framework.relations import PKOnlyObject
class MyModelSerializer(serializers.ModelSerializer):
def to_representation(self, instance):
"""Object instance -> Dict of primitive datatypes."""
ret = OrderedDict()
fields = self._readable_fields
for field in fields:
try:
attribute = field.get_attribute(instance)
except SkipField:
continue
# We skip `to_representation` for `None` values so that fields do
# not have to explicitly deal with that case.
#
# For related fields with `use_pk_only_optimization` we need to
# resolve the pk value.
check_for_none = attribute.pk if isinstance(attribute, PKOnlyObject) else attribute
if check_for_none is None:
value = None
else:
value = field.to_representation(attribute)
ret[field.field_name] = {
'value': value,
# You can find more field attributes here
# https://github.com/encode/django-rest-framework/blob/master/rest_framework/fields.py#L324
'verbose_name': field.label,
'read_only': field.read_only,
'write_only': field.write_only,
'help_text': field.help_text,
}
return ret