У меня есть проект с Django Rest Framework, и у меня есть комплекс ViewSet
, который использует несколько моделей и сериализаторов для соединения большого и сложного json. Все работает нормально, но я замечаю, что HotelSerializer
, то есть ModelSerializer
, возвращает сохраненное значение поля category
вместо понятного человеку значения его модели choices
.
Это модель:
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, где я получаю информацию о модели Hotel
:
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
},
Вы можете видеть, что поле Category
возвращает значение 'GRAND_TOURISM'
вместо его удобочитаемой версии его choices
: 'Grand Tourism'
. Он даже пропускает перевод, поэтому должен возвращать 'Gran Turismo'
.
Я не знаю, чего мне не хватает.