【问题标题】:my profile object is not getting serialized in the user serializer我的配置文件对象未在用户序列化程序中序列化
【发布时间】:2020-03-19 09:39:47
【问题描述】:

我正在使用 Django rest auth 对我的用户进行身份验证,效果很好。我的模型是如何设置的,我有用于身份验证的自定义用户模型,并且我还有一个使用信号创建的配置文件模型。

我希望当在其 URL 中获取用户时,该用户的配置文件也称为用户中的对象。

我的 models.py(我没有包含一些模型,比如用户管理器、技能等,因为我觉得它们不相关)

class User(AbstractBaseUser, PermissionsMixin):
    username = None
    email = models.EmailField(max_length=254, unique=True)
    fullname = models.CharField(max_length=250)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)


    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['fullname']

    objects = UserManager()


class Profile(models.Model):
    '''
    Note:
    profile photo is expecting photos link gotten from cloudnairy from the frontend
    - The height is calculated in feets and inches
    - Need to sort out location (lives in)
    - Need to add an age function
    - Need to add achievemnet as a foreign field 
    - Need to add education also as a foreign field
    - Add follow functionality
    '''
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    date_of_birth = models.DateField(blank=True, verbose_name="DOB", null=True)
    bio = models.TextField(max_length=500, blank=True, null=True)
    profile_photo = models.CharField(blank=True, max_length=300, null=True)
    skills = models.ManyToManyField(Skill)
    sex = models.CharField(max_length=1, choices=SEX, blank=True, null=True)
    type_of_body = models.CharField(max_length=8, choices=BODYTYPE, blank=True, null=True)
    feet = models.PositiveIntegerField(blank=True, null=True)
    inches = models.PositiveIntegerField(blank=True, null=True)
    lives_in = models.CharField(max_length=50, blank=True, null=True)
    updated_on = models.DateTimeField(auto_now_add=True)

serializers.py 代码

class ProfileSerializer(serializers.ModelSerializer):

    class Meta:
        model = Profile
        fields = "__all__"

        read_only_fields = ('pk',)


class CustomUserDetailsSerializer(serializers.ModelSerializer):

    profile = ProfileSerializer(read_only=True)

    class Meta:
        model = User
        fields = ('pk', 'email', 'fullname', 'profile')
        read_only_fields = ('email', 'fullname', 'profile')

view.py

class ListUsersView(APIView):

    permission_classes = [AllowAny]

    def get(self, request):
        user = User.objects.all()
        serializer = CustomUserDetailsSerializer(user, many=True)
        return Response(serializer.data)

urls.py

url(r'^list-users/$', ListUsersView.as_view(), name='list-users'),

我得到的 JSON 响应

[
    {
        "pk": 1,
        "email": "opeyemiodedeyi@gmail.com",
        "fullname": "opeyemiodedeyi"
    },
    {
        "pk": 2,
        "email": "odedeyiopeyemi94@gmail.com",
        "fullname": "opeyemi odedeyi"
    }
]

如何让配置文件显示在响应中?

【问题讨论】:

    标签: python django django-rest-framework django-rest-auth


    【解决方案1】:

    方法一

    使用source (DRF doc) 参数

    class CustomUserDetailsSerializer(serializers.ModelSerializer):
        profile = ProfileSerializer(read_only=True, source="profile_set")
    
        class Meta:
            model = User
            fields = ('pk', 'email', 'fullname', 'profile')
            read_only_fields = ('email', 'fullname', 'profile')

    由于ProfileUser是反向关系,所以需要指定反向查找,即profile_set

    方法-2

    在模型中更改related_name (Django doc)

    class Profile(models.Model):
        user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profile')
        ...

    建议的更改

    # models.py
    class Profile(models.Model):
        user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profiles')
        ...
    
    
    # serializers.py
    class CustomUserDetailsSerializer(serializers.ModelSerializer):
        profiles = ProfileSerializer(read_only=True)
    
        class Meta:
            model = User
            fields = ('pk', 'email', 'fullname', 'profiles')
            read_only_fields = ('email', 'fullname', 'profiles')

    参考文献

    1. What is reverse relationship?
    2. Django: Many-To-One Relation

    【讨论】:

    • 谢谢您,但是您推荐使用这两种方法中的哪一种?
    • 我建议将 related_name 更改为 profiles(请参阅,它是复数)并在序列化程序中也使用相同的相关名称,因为 Users 可以有多个 @987654333 @ 根据您的数据库结构。
    • 由于某种原因它对我不起作用,请您显示在序列化程序中要更改的内容,谢谢
    • 好的,现在有点用了,但是所有字段都显示为空。这就是当前的问题
    • 请提出一个新问题,因为您的新问题和 OP 不同
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-28
    • 1970-01-01
    • 2011-06-10
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    相关资源
    最近更新 更多