Django Rest Framework 方法返回 User 类型的对象不可 JSON 序列化

dar*_*tar 4 django django-models django-rest-framework

所以基本上我有一个 django 方法,我将其传递到序列化器中,但它返回错误User 类型的对象不是 JSON 可序列化这是我的文件:

模型.py:

from django.db import models
from django.contrib.auth.models import User


class Profile(models.Model):
    first_name = models.CharField(max_length=50, blank=True)
    last_name = models.CharField(max_length=50, blank=True)
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    friends = models.ManyToManyField(User, blank=True, related_name='friends')

    def friends_list(self):
        return self.friends.all()

    def number_of_friends(self):
        return self.friends.all().count()
Run Code Online (Sandbox Code Playgroud)

序列化器.py:

from rest_framework import serializers
from .models import Profile


class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = [
            'id',
            'first_name',
            'last_name',
            'user',
            'friends',
            'number_of_friends',
            'friends_list'
        ]
Run Code Online (Sandbox Code Playgroud)

该问题与“friends_list”方法有关,因为“number_of_friends”方法按预期完美运行。整个模型字段都有效,只是一种方法不起作用。我该如何解决这个问题?

JPG*_*JPG 12

这是因为friends_list(...)返回QuerySet对象的方法与 DRF 无法序列化相同。

为此,您需要使用serializers.SerializerMethodField单独的序列化器类来序列化User对象

from rest_framework import serializers
from .models import Profile


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ("username", "first_name", "email")


class ProfileSerializer(serializers.ModelSerializer):
    friends_list = serializers.SerializerMethodField()

    def get_friends_list(self, profile):
        return UserSerializer(profile.friends_list(), many=True).data

    class Meta:
        model = Profile
        fields = [
            'id',
            'first_name',
            'last_name',
            'user',
            'friends',
            'number_of_friends',
            'friends_list'
        ]
Run Code Online (Sandbox Code Playgroud)