【问题标题】:Django Serialize return id of user, but i need usernameDjango序列化返回用户的ID,但我需要用户名
【发布时间】:2025-12-17 13:10:01
【问题描述】:

这是我的模型:

class HighScore(models.Model):
    user = models.OneToOneField(UserManagement, on_delete=models.CASCADE)
    highScore = models.IntegerField(blank=True, null=True)
    createDate = models.DateTimeField()


    def __str__(self):
        return "{}_HighScore".format(self.user)

这是我的观点:

def pullUserNames(request):
    top_score = createHighScore()
    top_users = (HighScore.objects.order_by('-highScore').filter(highScore__in=top_score[:10]))
    top_users_serialized = serializers.serialize('json', top_users)
    top_users_json = json.loads(top_users_serialized)
    data = json.dumps(top_users_json)
    return HttpResponse(data)

回复是:

[{"model": "scoremg.highscore", "pk": 2, "fields": {"user": 2, "highScore": 650, "createDate": "2018-12-25T20:34:51.826Z"}}, {"model": "scoremg.highscore", "pk": 1, "fields": {"user": 1, "highScore": 271, "createDate": "2018-12-17T21:48:34.406Z"}}]

在此回复{"user": 2, "highScore": 650, "createDate": "2018-12-25T20:34:51.826Z"} 中,highScore 和 createDate 面子不错,但用户 id 不是用户名,我该如何编辑它以返回用户名?

我在上面视图的第二行之后测试 print(top_users),它打印了 --> user2_HighScore user1_HighScore

谢谢

【问题讨论】:

  • 类似的问题是here,希望对你有帮助。

标签: python json django response serialization


【解决方案1】:

使用 DRF 试试这个

serializer.py:

class HighScoreSerializer(serializers.ModelSerializer):
        user = serializers.SlugRelatedField(
            slug_field='username'
        )

    class Meta:
        model = HighScore
        fields = '__all__'

【讨论】:

    【解决方案2】:

    在序列化程序文件中,添加此代码以获取用户名而不是用户 ID。在这里,您将覆盖模型序列化程序的用户字段以获取用户名而不是用户 ID。

    类 SearchHistorySerializer(serializers.ModelSerializer):

    user = serializers.SlugRelatedField(
        read_only=True,
        slug_field='username'
    )
    class Meta:
        model = SearchHistory
        fields = '__all__'
    

    【讨论】:

    • 如果你能解释你的答案会更好。
    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    【解决方案3】:

    我认为,结合 QuerySet 的 Annotation 和序列化数据的自定义函数,您可以解决问题。

    这是一个示例:

    import json
    from django.db.models import F
    
    def custom_serializer(a):
        """
        Handy creation of the Queryset fields
        And we exclude the fields that starts by '__' 
        which are Django internal references
        This will lead to the representation of the annotated fields
        that are generated by the QuerySert annotation
        which are ignored by serializers.serialize() function
        """
        return [{
                 'model': a.model.__name__, 'pk': k.pk, 'fields': {
                     i: j for i, j in k.__dict__.items() if not i.startswith('_')
                 }
                } for k in a]
    
    # Here we annotate a new field called username
    # which holds the user's username using the F expression    
    top_users = HighScore.objects.order_by('highScore').filter(
        highScore__in=top_score[:10]
    ).annotate(username=F('user__username'))
    
    top_users_serialized = custom_serializer(top_users)
    print(json.dumps(top_users_serialized))
    

    你会得到这样的东西:

    [{
       "model": "scoremg.highscore",
       "pk": 2,
       "fields": {
         "id": 2,  # pk
         "user_id": 2  # your user id
         "username": "test",  # your user's username
         "highScore": 650,
         "createDate": "2018-12-25T20:34:51.826Z"
        }
     },
     ...
    ]
    

    编辑:

    不使用自定义函数的更好方法,您可以使用queryset.values() 方法,如下例:

    top_users = HighScore.objects.order_by('highScore').filter(
        highScore__in=top_score[:10]
    ).annotate(username=F('user__username'))
    top_users_serialized = [elm for elm in top.users.values()]
    print(json.dumps(top_users_serialized))
    

    你会得到这样的东西:

    [{
       "id": 2,  # pk
       "user_id": 2  # your user id
       "username": "test",  # your user's username
       "highScore": 650,
       "createDate": "2018-12-25T20:34:51.826Z"
      },
      ...
    ]
    

    更多信息请参考:F() expressionQuerySet AnnotationQuerySet values

    【讨论】:

      【解决方案4】:

      在serializer.py文件的序列化器类中,添加如下代码:

      user = serializers.SlugRelatedField(
              read_only=True,
              slug_field='username'
          )
      

      这将告诉您的序列化程序从用户表中获取并返回用户名字段。

      【讨论】: