【问题标题】:Django Rest Framework creating Profile instance instead of updating ProfileDjango Rest Framework 创建 Profile 实例而不是更新 Profile
【发布时间】:2023-03-10 01:18:01
【问题描述】:

我想通过将数据发送到 url update_profile/ 来更新用户的 Profile 实例

我正在使用:

curl -X PUT -H "Authorization: Token sometoken" -d "name=somename&age=20&user=1" 127.0.0.1:8000/update_profile/

我得到的错误是:{"user":["This field must be unique."]}

似乎错误是因为请求创建了一个新的 Profile 实例,而同一用户已经存在另一个 Profile 实例。但我只想为用户更新当前的 Profile 实例。知道为什么我的代码会尝试创建一个新实例而不是更新它吗?

views.py

class UserProfileChangeAPIView(generics.UpdateAPIView, mixins.UpdateModelMixin):

    permission_classes = (
    permissions.IsAuthenticated,
    UserIsOwnerOrReadOnly,
    )
    serializer_class = UpdateProfileSerializer
    parser_classes = (MultiPartParser, FormParser,)

    def get_queryset(self, *args, **kwargs):
        queryset = Profile.objects.filter(user=self.request.user)
        return queryset

    def get_object(self):
        self.request.user.profile

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

    def update(self, request, pk=None):
        try:
            self.request.user.profile

        except Http404:
            return Response(
                {'detail': 'Not found'}, status=status.HTTP_404_NOT_FOUND)
        return super(UserProfileChangeAPIView, self).update(request, pk)

urls.py

     url(r'^update_profile/$', UserProfileChangeAPIView.as_view(), name='update_profile'),

序列化器.py

 class UpdateProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = [
            'name',
            'age',
            'user',
        ]

models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=100, null=True)
    age = models.PositiveIntegerField(null=True)

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    您不应在帖子数据中包含user,因为您已经在get_object()get_queryset() 中获取了当前登录用户的个人资料

    因为 Profile 和 User 之间的关系是一个OnetoOneField,所以不能有多个Profile 链接到同一个User

    我预计(根据您收到的错误)这里发生的情况是您以 User 的身份登录(例如 id 3),然后尝试更新 Profile 以指向 User id 1。

    【讨论】:

    • 似乎 id 不是问题的原因,因为它与发送请求的用户的用户 id 相同。如果我在序列化程序和放入数据中跳过用户,则会出现此错误:NOT NULL constraint failed:rest_auth_profile.user_id
    【解决方案2】:

    我能够解决这样的问题,并且不需要在 url 中使用 pk:

    序列化器.py

     class UpdateProfileSerializer(serializers.ModelSerializer):
         class Meta:
            model = Profile
            fields = [
                'name',
                'age',
            ]
    

    views.py

    class ProfileUpdateAPIView(UpdateAPIView):
        serializer_class = UpdateProfileSerializer
    
        def get_object(self):
            queryset = Profile.objects.filter(user=self.request.user)
            obj = queryset[0]
            return obj
    

    urls.py:

    url(r'^update/$', ProfileUpdateAPIView.as_view(), name='update'),
    

    卷曲:

     curl -X PUT  -H "Authorization: Token sometoken" -d "name=newname&age=20" 127.0.0.1:8000/update/
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-02
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      相关资源
      最近更新 更多