在一个请求中更新用户个人资料和用户
Update user profile and user in one request
提前感谢您的关注。
目标:
简而言之:仅当单个视图发生变化时才更新 django 用户对象和自定义用户配置文件对象。
问题:
对于初学者来说,这是我第一次尝试做这样的事情,所以它可能非常简单,我只是忽略了它。
它似乎在验证步骤上失败并且我收到 HTTP 400 错误说 'username must be unique',即使我没有发送会更改当前用户用户名的更改。现在我可能可以使用 django-rest-auth 内置的视图来更新用户部分,然后创建一个只更新配置文件的自定义视图。但这似乎很老套和愚蠢,但如果这是可行的方法,那么我会这样做。
我尝试过的东西:
- 尝试了放置和补丁。同样的结果。
- 尝试重写 put 和 patch 方法以在验证之前从
request.data
中删除用户名字段是否相同,但这给出了另一个错误,指出它是必需的。
- 尝试覆盖序列化程序中的更新方法,遇到了一个问题,我不知道如何更新嵌套字段。
- 谷歌搜索无止境。
- 考虑编写自定义验证器。但我不知道从哪里开始,我想让它尽可能简单并且更喜欢内置的东西。
序列化程序:
class UserSerializer(ModelSerializer):
class Meta(UserDetailsSerializer.Meta):
model = User
fields = ('username', 'email', 'first_name', 'last_name')
read_only_fields = ('email', )
class UserProfileSerializer(ModelSerializer):
user = UserSerializer(required=True, many=False)
games = UserGameProfileSerializer(required=False, many=True)
class Meta:
model = UserProfile
fields = ('premium', 'user', 'games')
查看:
class UserProfileUpdateView(generics.UpdateAPIView):
# authentication_classes = (authentication.TokenAuthentication,)
# permission_classes = (permissions.IsAuthenticated,)
serializer_class = UserProfileSerializer
def get_queryset(self):
return UserProfile.objects.filter(user__username__exact=self.request.user).all()
def get_object(self):
return UserProfile.objects.filter(user__username__exact=self.request.user).get()
免责声明
我终于弄明白了,我只是回答以备日后参考。我不确定这是完成任务的最佳做法还是最简单的方法。然而,这就是我能够想出的。
我将视图更改为更简单,而不是那种看起来令人讨厌的过滤器查询,我发现我可以做一个获取对象,只需说 user=self.request.user
就可以得到我需要的东西。
查看
class UserProfileUpdateView(generics.UpdateAPIView):
authentication_classes = (authentication.TokenAuthentication,)
permission_classes = (permissions.IsAuthenticated,)
serializer_class = UserProfileSerializer
def get_object(self):
return UserProfile.objects.get(user=self.request.user)
然后在序列化程序中,我想出了如何更新嵌套对象,这正是需要完成的工作。现在我意识到目前我只是在更新内置的 django 对象。但很快我将向用户配置文件添加更多字段,并且需要更新这些字段,如果用户对象发生更改,我想在同一请求中更新它们。
在更新功能中,您可以使用 self.data
访问请求数据,在那里我能够访问包含用户信息的字典。这样我就能够查询用户对象,然后使用 UserSerializer 我能够验证数据并调用更新传递我查询的用户和来自序列化程序的验证数据。
序列化器
class UserProfileSerializer(ModelSerializer):
user = UserSerializer(required=True, many=False)
games = UserGameProfileSerializer(required=False, many=True)
class Meta:
model = UserProfile
fields = ('premium', 'user', 'games')
read_only_fields = ('premium', )
def update(self, instance, validated_data):
user_data = validated_data.pop('user')
game_data = validated_data.pop('games')
username = self.data['user']['username']
user = User.objects.get(username=username)
print user
user_serializer = UserSerializer(data=user_data)
if user_serializer.is_valid():
user_serializer.update(user, user_data)
instance.save()
return instance
提前感谢您的关注。
目标:
简而言之:仅当单个视图发生变化时才更新 django 用户对象和自定义用户配置文件对象。
问题:
对于初学者来说,这是我第一次尝试做这样的事情,所以它可能非常简单,我只是忽略了它。
它似乎在验证步骤上失败并且我收到 HTTP 400 错误说 'username must be unique',即使我没有发送会更改当前用户用户名的更改。现在我可能可以使用 django-rest-auth 内置的视图来更新用户部分,然后创建一个只更新配置文件的自定义视图。但这似乎很老套和愚蠢,但如果这是可行的方法,那么我会这样做。
我尝试过的东西:
- 尝试了放置和补丁。同样的结果。
- 尝试重写 put 和 patch 方法以在验证之前从
request.data
中删除用户名字段是否相同,但这给出了另一个错误,指出它是必需的。 - 尝试覆盖序列化程序中的更新方法,遇到了一个问题,我不知道如何更新嵌套字段。
- 谷歌搜索无止境。
- 考虑编写自定义验证器。但我不知道从哪里开始,我想让它尽可能简单并且更喜欢内置的东西。
序列化程序:
class UserSerializer(ModelSerializer):
class Meta(UserDetailsSerializer.Meta):
model = User
fields = ('username', 'email', 'first_name', 'last_name')
read_only_fields = ('email', )
class UserProfileSerializer(ModelSerializer):
user = UserSerializer(required=True, many=False)
games = UserGameProfileSerializer(required=False, many=True)
class Meta:
model = UserProfile
fields = ('premium', 'user', 'games')
查看:
class UserProfileUpdateView(generics.UpdateAPIView):
# authentication_classes = (authentication.TokenAuthentication,)
# permission_classes = (permissions.IsAuthenticated,)
serializer_class = UserProfileSerializer
def get_queryset(self):
return UserProfile.objects.filter(user__username__exact=self.request.user).all()
def get_object(self):
return UserProfile.objects.filter(user__username__exact=self.request.user).get()
免责声明
我终于弄明白了,我只是回答以备日后参考。我不确定这是完成任务的最佳做法还是最简单的方法。然而,这就是我能够想出的。
我将视图更改为更简单,而不是那种看起来令人讨厌的过滤器查询,我发现我可以做一个获取对象,只需说 user=self.request.user
就可以得到我需要的东西。
查看
class UserProfileUpdateView(generics.UpdateAPIView):
authentication_classes = (authentication.TokenAuthentication,)
permission_classes = (permissions.IsAuthenticated,)
serializer_class = UserProfileSerializer
def get_object(self):
return UserProfile.objects.get(user=self.request.user)
然后在序列化程序中,我想出了如何更新嵌套对象,这正是需要完成的工作。现在我意识到目前我只是在更新内置的 django 对象。但很快我将向用户配置文件添加更多字段,并且需要更新这些字段,如果用户对象发生更改,我想在同一请求中更新它们。
在更新功能中,您可以使用 self.data
访问请求数据,在那里我能够访问包含用户信息的字典。这样我就能够查询用户对象,然后使用 UserSerializer 我能够验证数据并调用更新传递我查询的用户和来自序列化程序的验证数据。
序列化器
class UserProfileSerializer(ModelSerializer):
user = UserSerializer(required=True, many=False)
games = UserGameProfileSerializer(required=False, many=True)
class Meta:
model = UserProfile
fields = ('premium', 'user', 'games')
read_only_fields = ('premium', )
def update(self, instance, validated_data):
user_data = validated_data.pop('user')
game_data = validated_data.pop('games')
username = self.data['user']['username']
user = User.objects.get(username=username)
print user
user_serializer = UserSerializer(data=user_data)
if user_serializer.is_valid():
user_serializer.update(user, user_data)
instance.save()
return instance