如何从两个模型编辑 django rest 框架中的用户配置文件并保存更改

How to edit user profile in django rest framework from two models and save the change

我正在尝试创建一个端点来编辑下面的用户模型和自定义配置文件模型。

models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField(max_length=500)
    location = models.CharField(max_length=50)
    image = models.ImageField(default='default.jpg', upload_to='profile')

在常规的 django 中我会这样做:

views.py

def edit_profile(request):
    if request.method == 'POST':
        form = EditProfileForm(request.POST, instance=request.user)
        extended_profile_form = ProfileForm(request.POST,
                                            request.FILES,
                                            instance=request.user.profile)        
        if form.is_valid() and extended_profile_form.is_valid():
            form.save()
            extended_profile_form.save()
            return redirect('accounts:profile')
    else:
        form = EditProfileForm(instance=request.user)
        extended_profile_form = ProfileForm(instance=request.user.profile)

    context = {
            'form':form,
            'extended_profile_form':extended_profile_form
    }

    return render(request, 'accounts/edit-profile.html', context)

django rest 框架的等价物是什么?

我试过:

views.py (Django Rest 框架)

@api_view(['GET','PUT'])
def profile(request):
    if request.method == 'GET':
        user  = User.objects.filter(username=request.user)
        profile_user = Profile.objects.filter(user=request.user)
        serializer_user = UserSerializer(user, many=True)
        serializer_profile_user = ProfileSerializer(profile_user, many=True)
        result = {'serializer_user': serializer_user.data, 'serializer_profile_user': serializer_profile_user.data}
        return Response(result)
    elif request.method == 'PUT':
        user  = User.objects.filter(username=request.user)
        profile_user = Profile.objects.filter(user=request.user)
        serializer_user = UserSerializer(user, data=request.data)
        serializer_profile_user = ProfileSerializer(profile_user, data=request.data)
        if serializer_user.is_valid() and serializer_profile_user.is_valid():
            serializer_user.save()
            serializer_profile_user.save()
            result = {'serializer_user': serializer_user.data, 'serializer_profile_user': serializer_profile_user.data}
            return Response(result)
        result = {'serializer_user': serializer_user.data, 'serializer_profile_user': serializer_profile_user.data}
        return Response(result.errors, status=status.HTTP_400_BAD_REQUEST)

当我浏览端点时,它确实显示 serializer_userserializer_profile_user 数据,但我无法使用 DRF 可浏览 API.[=15 编辑任何这些数据=]

我认为上面的代码是否等同于普通 django 中用于编辑用户配置文件的代码?

我觉得不错,但你需要替换它:

 if request.method == 'GET':
    user  = User.objects.filter(username=request.user)

有了这个:

 if request.method == 'GET':
    try:
        user  = User.objects.get(id=request.user.id)
    except User.DoesNotExist:
         return Response(data='no such user!', status=status.HTTP_400_BAD_REQUEST)
    # you need to use objects.get because objects.filter returns a queryset not an abject

因为,request.user 是 User 模型的一个实例,你不能将它与用户的属性(在你的例子中是用户名)进行比较

PS:您的 PUT 方法也一样。

希望对您有所帮助!

看。你可以让它变得更容易。让我们以 Post 模型(例如):

class Post(models.Model):
    author = models.ForeignKey(base.AUTH_USER_MODEL, on_delete=models.CASCADE)
    title = models.CharField(max_length=50)
    text = models.TextField()
    likes = models.ManyToManyField(base.AUTH_USER_MODEL, blank=True, related_name='post_likes')
    created_date = models.DateTimeField(default=timezone.now)

你应该在你的序列化器中描述它(序列化器类似于 DTO。它将数据转换为服务友好的 JSON 视图):

class PostCreateUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ['id', 'title', 'text']

最后一部分 - 端点:

class PostUpdateView(UpdateAPIView):
    serializer_class = PostCreateUpdateSerializer

    def get_queryset(self):
        return Post.objects.filter(author=self.request.user)

table使用 CBV Django and DRF

会更舒服

还有一件事。您不应该为您的用户模型再创建一个 table。这是由于 BaseUser 模型的扩展。 Link for help