我在User模型和UserProfile模型之间建立了一对一的关系。 UserProfile模型包含有关用户的其他信息,并且在保存User模型后立即创建。在UserProfile上设置了OneToOne字段。
当我访问有关UserProfile的任何视图时,序列化的User数据看起来都很好,但是我也希望UserProfile数据出现在User视图中,我想知道如何在UserSerializer中指定它。
编辑:我需要UserProfile数据,以便可以对UserProfile ID进行轻松查找以更改有关User的信息。我将拥有用户ID客户端。理想情况下,我想查找具有该ID的User,找到UserProfile ID(以及其他UserProfile数据),以便随后可以更改与该User相关联的UserProfile的数据。
示例:用户1已通过身份验证。注册后,我收集了一些信息,因此我将视图称为/api/users/1/
,该视图告诉我ID为20的用户个人资料与该用户相关联。然后,我可以使用新数据更新该用户个人资料。我不能总是假设用户ID 1与用户个人资料ID 1相关联。
编辑2:解决了类似于安吉拉的答案:
class UserSerializer(serializers.ModelSerializer):
user_profile = UserProfileSerializer(source="userprofile")
class Meta:
model = User
fields = (
"id",
"username",
"email",
"first_name",
"last_name",
"groups",
"user_profile"
)
serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = (
"id",
"username",
"email",
"first_name",
"last_name",
"groups"
)
class UserProfileSerializer(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = UserProfile
fields = (
"user",
"current_city",
"current_country"
)
models.py
class UserProfile(models.Model):
user = models.OneToOneField(
User,
on_delete=models.CASCADE
)
avatar = models.FileField(
upload_to="uploads",
blank=True
)
age = models.IntegerField(
null=True
)
created_at = models.DateTimeField(
auto_now_add=True
)
current_city = models.CharField(
max_length=255,
blank=True
)
current_country = models.CharField(
max_length=255,
blank=True
)
答案 0 :(得分:2)
我认为,您应该为此目的使用 两个UserProfileSerializer
,
#serializer.py
class UserProfileSerializer_Temp(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = (
"user",
"current_city",
"current_country"
)
class UserSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
user_profile = kwargs.pop('user_profile', True)
super().__init__(*args, **kwargs)
if user_profile is False:
self.fields.pop('user_profile', None)
user_profile = UserProfileSerializer_Temp(source='userprofile_set')
class Meta:
model = User
fields = (
"id",
"username",
"email",
"first_name",
"last_name",
"groups",
"user_profile"
)
class UserProfileSerializer_New(UserProfileSerializer_Temp):
user = UserSerializer(user_profile=False)
#views.py
class UserProfileAPI(ModelViewSet):
serializer_class = UserProfileSerializer_New
queryset = UserProfile.objects.all()
class UserAPI(ModelViewSet):
serializer_class = UserSerializer
queryset = User.objects.all()
user_profile=False
有什么意义?
它就像一个简单的标志。如果我们没有从UserProfileSerializer_New
传递类似的信息,它将序列化 UserProfile
两次 。看到这个Screenshot --- image
治愈反应
1。 UserAPI
2。 UserProfileAPI
答案 1 :(得分:0)
因此,要使用户配置文件信息可在用户序列化器中查看,并在用户序列化器中具有用户信息,我建议您按以下方式使用序列化器源争论-
推荐方法
这是基于以下假设:更新用户配置文件时,您不想更新实际用户模型中的任何信息。您可以使用用户端点来做到这一点。
class UserProfileSerializer(serializers.ModelSerializer):
first_name = serializers.CharField(source='user.first_name',read_only=True)
last_name = serializers.CharField(source='user.second_name',read_only=True)
...... #(other user fields you want to include)
......
......
class Meta:
model = UserProfile
fields = (
"first_name",
"last_name",
"current_city",
"current_country",
......., # any other user fields
.......
)
class UserSerializer(serializers.ModelSerializer):
user_profile = UserProfileSerializer(partial=True, required=False)
class Meta:
model = User
fields = (
"id",
"username",
"email",
"first_name",
"last_name",
"groups",
"user_profile"
)
这将为您提供用户对象内的user_profile的嵌套表示形式,其中还将包含源字段,但是您可以选择忽略它。
另一种方法
否则,如果您确实希望在两个序列化程序中都使用嵌套结构,则可以使用不同的序列化程序,但不确定使用情况是什么。
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = (
"current_city",
"current_country",
......., # any other user_profile only fields
.......
)
class UserSerializer(serializers.ModelSerializer):
user_profile = UserProfileSerializer(partial=True, required=False)
class Meta:
model = User
fields = (
"id",
"username",
"email",
"first_name",
"last_name",
"groups",
"user_profile"
)
class UserSerializerNew(serializers.ModelSerializer):
class Meta:
model = User
fields = (
"id",
"username",
"email",
"first_name",
"last_name",
"groups"
)
class UserProfileSerializerNew(serializers.ModelSerializer):
user = UserSerializerNew(read_only=True)
class Meta:
model = UserProfile
fields = (
"current_city",
"current_country",
"user"
)