Сериализатор django rest: порядок появления полей - PullRequest
0 голосов
/ 23 октября 2019

Можно ли указать, в каком порядке поля появятся в сериализованной модели?

Чтобы не было путаницы, при поиске ответов на это я нашел много предложений по упорядочению объектов в списке. вид, но это не то, что я ищу.

Я действительно имею в виду для данной модели, я хотел бы, чтобы их поля после сериализации отображались в определенном порядке. У меня есть довольно сложный сериализованный объект, содержащий много вложенных сериализаторов, которые появляются первыми. Вместо этого я бы предпочел, чтобы ключевые идентифицирующие поля, такие как name и slug, отображались первыми для удобства чтения.

Заранее извиняюсь, если этот вопрос дублируется, но я не нашел соответствующих ответов.

Решение На основе решения @ Toni-Sredanović я реализовал следующее решение

def promote_fields(model: models.Model, *fields):
    promoted_fields = list(fields)
    other_fields = [field.name for field in model._meta.fields if field.name not in promoted_fields]
    return promoted_fields + other_fields


class MySerializer(serializers.ModelSerializer):
    ...
    class Meta:
        model = MyModel
        fields = promote_fields(model, 'id', 'field1', 'field2')

1 Ответ

2 голосов
/ 23 октября 2019

Для этого вы можете указать, какие поля вы хотите показать и их порядок в class Meta:

    class Meta:
        fields = ('id', 'name', 'slug', 'field_1', 'field_2', ..., )

Вот полный пример:

class TeamWithGamesSerializer(serializers.ModelSerializer):
    """
    Team ModelSerializer with home and away games.
    Home and away games are nested lists serialized with GameWithTeamNamesSerializer.
    League is object serialized with LeagueSerializer instead of pk integer.
    Current players is a nested list serialized with PlayerSerializer.
    """
    league = LeagueSerializer(many=False, read_only=True)

    home_games = GameWithTeamNamesSerializer(many=True, read_only=True)
    away_games = GameWithTeamNamesSerializer(many=True, read_only=True)

    current_players = PlayerSerializer(many=True, read_only=True)

    class Meta:
        model = Team
        fields = ('id', 'name', 'head_coach', 'league', 'current_players', 'home_games', 'away_games', 'gender')

И результат:

{
    "id": 1,
    "name": "Glendale Desert Dogs",
    "head_coach": "Coach Desert Dog",
    "league": {
        "id": 1,
        "name": "Test league 1"
    },
    "current_players": [
        {
            "id": "rodriem02",
            "first_name": "Emanuel",
            "last_name": "Rodriguez",
            "current_team": 1
        },
        {
            "id": "ruthba01",
            "first_name": "Babe",
            "last_name": "Ruth",
            "current_team": 1
        }
    ],
    "home_games": [
        {
            "id": 6,
            "team_home": {
                "id": 1,
                "name": "Glendale Desert Dogs"
            },
            "team_away": {
                "id": 2,
                "name": "Mesa Solar Sox"
            },
            "status": "canceled",
            "date": "2019-10-01"
        },
        {
            "id": 7,
            "team_home": {
                "id": 1,
                "name": "Glendale Desert Dogs"
            },
            "team_away": {
                "id": 2,
                "name": "Mesa Solar Sox"
            },
            "status": "",
            "date": "2019-10-04"
        }
    ],
    "away_games": [
        {
            "id": 3,
            "team_home": {
                "id": 2,
                "name": "Mesa Solar Sox"
            },
            "team_away": {
                "id": 1,
                "name": "Glendale Desert Dogs"
            },
            "status": "canceled",
            "date": "2019-10-02"
        }
    ],
    "gender": "M"
}

Если вы просто используете fields = '__all__' будет использоваться порядок по умолчанию, а именно:

  1. идентификатор объекта
  2. поля, указанные в сериализаторе
  3. полей, указанных в модели

Лучшее, что я могу сейчас вспомнить относительно вашего комментария о создании полей, - это получение полей в модели, не совсем уверенный, как получить доступ к тому, что вы определили вСериализатор, так что вам все равно нужно было бы написать это вручную.

Вот как вы могли бы сделать это с моим примером (это привело бы к появлению name и gender сверху):

    class Meta:
        model = Team
        fields = ('name', 'gender')\
                 + tuple([field.name for field in model._meta.fields if field.name not in ('name', 'gender')])\
                 + ('league', 'home_games', 'away_games', 'current_players')

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...