Python Django Rest Framework模型对象返回带有选项的字段的存储值

Python Django Rest Framework模型对象返回带有选项的字段的存储值,python,django,django-rest-framework,Python,Django,Django Rest Framework,我有一个使用Django Rest框架的项目,我有一个复杂的ViewSet,它使用多个模型和序列化程序来合成一个大型复杂的json。一切正常,但我注意到HotelSerializer,即ModelSerializer,正在返回fieldcategory的存储值,而不是其model选项的可读值 这就是模型: class Hotel(models.Model): ONE_STAR = '*' TWO_STARS = '**' THREE_STARS = '***' F

我有一个使用Django Rest框架的项目,我有一个复杂的
ViewSet
,它使用多个模型和序列化程序来合成一个大型复杂的json。一切正常,但我注意到
HotelSerializer
,即
ModelSerializer
,正在返回field
category
的存储值,而不是其model
选项的可读值

这就是模型:

class Hotel(models.Model):
    ONE_STAR = '*'
    TWO_STARS = '**'
    THREE_STARS = '***'
    FOUR_STARS = '****'
    FIVE_STARS = '*****'
    GRAND_TOURISM = 'GRAND_TOURISM'
    NA = 'NA'
    SPECIAL = 'SPECIAL'
    ECO = 'ECO'
    BOUTIQUE = 'BOUTIQUE'

    HOTEL_CATEGORY_CHOICES = (
        (ONE_STAR, _('*')),
        (TWO_STARS, _('**')),
        (THREE_STARS, _('***')),
        (FOUR_STARS, _('****')),
        (FIVE_STARS, _('*****')),
        (GRAND_TOURISM, _('Grand Tourism')),
        (NA, _('NA')),
        (SPECIAL, _('Special')),
        (ECO, _('Eco-Hotel')),
        (BOUTIQUE, _('Boutique-Hotel'))
    )

    company = models.OneToOneField(Company, on_delete=models.CASCADE, primary_key=True, verbose_name=_('Company'))
    code = models.CharField(max_length=10, verbose_name=_('Code'))
    zone = models.ForeignKey(Zone, on_delete=models.PROTECT, related_name='hotels', verbose_name=_('Zone'))
    category = models.CharField(max_length=20, choices=HOTEL_CATEGORY_CHOICES, verbose_name=_('Category'))
    capacity = models.IntegerField(verbose_name=_('Capacity'))
    position = models.DecimalField(max_digits=11, decimal_places=2, default=0.00, verbose_name=_('Position'))
    in_pickup = models.BooleanField(default=False, verbose_name=_('In pickup?'))
    is_active = models.BooleanField(default=True, verbose_name=_('Is active?'))
    latitude = models.FloatField(null=True, blank=True, verbose_name=_('Latitude'))
    longitude = models.FloatField(null=True, blank=True, verbose_name=_('Longitude'))
这是序列化程序:

class HotelSerializer(serializers.ModelSerializer):
    category = serializers.ChoiceField(choices=models.Hotel.HOTEL_CATEGORY_CHOICES)
    class Meta:
        model = models.Hotel
        fields = ('company', 'code', 'zone', 'category', 'capacity', 'position', 'in_pickup', 'is_active', 'latitude', 'longitude')
        depth = 4

    def __init__(self, *args, **kwargs):
        exclude = kwargs.pop('exclude', None)

        super(HotelSerializer, self).__init__(*args, **kwargs)

        if exclude is not None:
            for field_name in exclude:
                self.fields.pop(field_name)
这是ViewSet函数,我从中获取
酒店
车型信息:

def get_hotel(self, company_id):
    hotel = Hotel.objects.get(company=company_id)

    import ReservationsManagerApp.serializers
    return ReservationsManagerApp.serializers.HotelSerializer(hotel, exclude=('company',)).data
这就是我得到的结果:

"hotel": {
        "code": "xxxx...",
        "zone": {
            "id": 1,
            "name": "Zona hotelera",
            "city": {
                "id": 5,
                "name": "Cancun",
                "code": "998",
                "state": {
                    "id": 2,
                    "name": "Quintana Roo",
                    "code": "98",
                    "country": {
                        "id": 1,
                        "name": "Mexico",
                        "code": "MX",
                        "calling_code": "52"
                    }
                }
            }
        },
        "category": "GRAND_TOURISM",
        "capacity": 300,
        "position": "1.00",
        "in_pickup": true,
        "is_active": true,
        "latitude": null,
        "longitude": null
    },
您可以看到
类别
字段返回值
'GRAND_TOURISM'
,而不是其
选项的可读版本
'GRAND TOURISM'
。它甚至错过了翻译,因此它必须返回
“Gran Turismo”


我不知道我遗漏了什么。

这是正确的行为,但很容易修复

一个解决办法是只做一件事

class HotelSerializer(serializers.ModelSerializer):
  category = serializers.ChoiceField(choices=Hotel.HOTEL_CATEGORY_CHOICES)
  company = CompanySerializer()
  ...

非常感谢,但是没有用。我得到了完全相同的结果。太糟糕了。我得去试试,看看为什么不行。我相信我以前用过。请注意,DRF不能以这种方式工作是有原因的。就像使用定义变量来确保在用户友好的字符串更改时代码不会更改一样,您应该为API用户提供同样的好处。因此,通常要做的是为用户提供一个简短的代码,这与显示字符串不同。