我的个人资料对象在用户序列化程序中没有被序列化。
我的个人资料对象在用户序列化程序中没有被序列化。
我正在使用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"
}
]
我如何使配置文件在响应中显示出来?
问题原因:用户序列化器中的"profile"对象没有被序列化的原因是,由于"Profile"与"User"之间是反向关系,所以需要指定反向查找的关联名称。
解决方法:有两种解决方法可以解决这个问题。
方法一:使用source参数,指定反向查找的关联名称。
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')
方法二:在模型中更改related_name参数的值。
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?](https://stackoverflow.com/questions/17328910)
2. [Django: Many-To-One Relation](https://docs.djangoproject.com/en/2.2/topics/db/examples/many_to_one/)
建议使用修改related_name为"profiles",并在序列化器中使用相同的关联名称,因为根据数据库结构,"Users"可以拥有多个"profiles"。
请注意,本文中的代码为Python代码。