django rest序列化程序:排序字段外观

django rest序列化程序:排序字段外观,django,serialization,django-rest-framework,Django,Serialization,Django Rest Framework,是否可以指定序列化模型中出现的顺序字段 为了确保没有混淆,在搜索这个问题的答案时,我发现了很多关于在列表视图中对对象进行排序的建议,但这不是我想要的 我的意思是,对于一个给定的模型,我希望它们的字段一旦序列化,就会以特定的顺序出现。我有一个相当复杂的序列化对象,其中包含许多嵌套序列化程序,它们首先出现。为了可读性,我宁愿先显示键标识字段,例如name和slug 如果这个问题重复,我会提前道歉,但我没有找到任何相关的回答 解决方案 基于@Toni Sredanović解决方案,我实施了以下解决方案

是否可以指定序列化模型中出现的顺序字段

为了确保没有混淆,在搜索这个问题的答案时,我发现了很多关于在列表视图中对对象进行排序的建议,但这不是我想要的

我的意思是,对于一个给定的模型,我希望它们的字段一旦序列化,就会以特定的顺序出现。我有一个相当复杂的序列化对象,其中包含许多嵌套序列化程序,它们首先出现。为了可读性,我宁愿先显示键标识字段,例如
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')

为此,您可以指定要显示的字段及其在
类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='\uuuuu all\uuuuu'
将使用默认顺序,即:

  • 对象id
  • 序列化程序中指定的字段
  • 模型中指定的字段
  • 关于您关于生成字段的评论,我现在能想到的最好的方法是在模型中获取字段,但不确定如何访问您在序列化程序中定义的内容,所以您仍然需要手动编写

    下面是如何使用我的示例(这将使
    名称
    性别
    显示在顶部):


    为此,您可以指定要显示的字段及其在
    类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='\uuuuu all\uuuuu'
    将使用默认顺序,即:

  • 对象id
  • 序列化程序中指定的字段
  • 模型中指定的字段
  • 关于您关于生成字段的评论,我现在能想到的最好的方法是在模型中获取字段,但不确定如何访问您在序列化程序中定义的内容,所以您仍然需要手动编写

    下面是如何使用我的示例(这将使
    名称
    性别
    显示在顶部):


    谢谢,我现在用的是“全部”。我将看看是否可以通过编程方式从模型中生成字段列表(即,先输入名称、slug,然后是所有其他字段)。嘿,为我的答案编辑了如何从模型中生成字段列表。希望有帮助。谢谢Toni,这就是我使用的方法,并单独解释了轻微的改进。注意:在rest_框架文档中,字段应该是列表,而不是元组。但这似乎不是问题。谢谢,我现在用的是“全部”。我将看看是否可以通过编程方式从模型中生成字段列表(即,先输入名称、slug,然后是所有其他字段)。嘿,为我的答案编辑了如何从模型中生成字段列表。希望有帮助。谢谢Toni,这就是我使用的方法,并单独解释了轻微的改进。注意:在rest_框架文档中,字段应该是列表,而不是元组。但这似乎不是一个问题。