Объект модели Django Rest Framework возвращает сохраненное значение поля с вариантами выбора - PullRequest
0 голосов
/ 28 июня 2018

У меня есть проект с 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'.

Я не знаю, чего мне не хватает.

1 Ответ

0 голосов
/ 28 июня 2018

Это правильное поведение AFAIK, но его легко исправить.

Одним из решений является просто

class HotelSerializer(serializers.ModelSerializer):
  category = serializers.ChoiceField(choices=Hotel.HOTEL_CATEGORY_CHOICES)
  company = CompanySerializer()
  ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...