【问题标题】:How to retrieve all items created by a user using the django rest framework如何使用 django rest 框架检索用户创建的所有项目
【发布时间】:2019-11-18 11:45:53
【问题描述】:

我正在尝试仅获取属于特定用户的课程,下面我有我用来尝试实现此目的的模型、序列化程序和视图。如果我从视图中删除整个 get_queryset 函数,则 api 将返回相应的用户以及每个用户创建的每门课程。如果 get_queryset 仍然存在,则 api 始终返回未找到用户,并且仍然提供所有存在的课程。谁能指出我如何才能达到我想要的结果。

查看:

class UserDetail(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = [IsProfileOwnerOrReadOnly]
    # queryset = User.objects.all()
    serializer_class = UserSerializer

    def get_queryset(self):
        user = self.request.user
        queryset = User.objects.all()
        if user is not None:
            queryset = queryset.filter(courses__owner_id=user.id)
        return queryset

序列化器

class UserSerializer(serializers.ModelSerializer):
    courses = serializers.PrimaryKeyRelatedField(
        many=True, queryset=Course.objects.all())
    class Meta:
        model = User
        fields = ['id', 'username', 'courses']

型号

class Course (models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField()
    pub_date = models.DateField(default=date.today)
    owner = models.ForeignKey('auth.User', related_name='courses', on_delete=models.CASCADE)
    def __str__(self):
        return self.title

【问题讨论】:

  • 您是如何定义映射到您的视图的 URL 的?如果您希望由特定用户创建课程,您的 URL 必须允许选择用户 ID。 https://api.yourcourses.com/user/<user_id>/courses 之类的东西,你可以用 django-rest-framework.org/api-guide/routers/#drf-nested-routers 实现
  • 如果要使用认证中间件给出的user,这种情况下应该可以直接使用self.request.user.coursesCourses.objects.filter(owner=self.request.user)
  • @AlexandreS url 以 path('users//', views.UserDetail.as_view()) 的形式给出,

标签: django django-rest-framework


【解决方案1】:

您需要按用户过滤对象

    class CreatePostsView(viewsets.ModelViewSet):
        model = Post
        serializer_class = PostsSerializer


        def get_queryset(self):
            user = self.request.user

            return Post.objects.filter(owner=user)

【讨论】:

    【解决方案2】:
     class CoursesByOwnerView(RetrieveModelMixin, GenericViewSet):
        serializer_class = YourModelSerializer
        authentication_classes =[TokenAuthentication,]
        permission_classes = [IsAuthenticated,]
    
    
        def list(self, request, *args, **kwargs):
           course_taker = self.request.user
           courses = YourModel.objects.filter(owner=course_taker).values('your_model_fields')
           return Response(courses)
    

    【讨论】:

      【解决方案3】:

      鉴于你在 cmets 中的回答:

      • 要么使用身份验证中间件提供的self.request.user。在这种情况下,它仅适用于经过身份验证的用户,您无法查看其他用户的课程。

      • 要么使用你提到的端点users/<int:pk>/。在这种情况下,您可以通过以下方式获取用户:

      class UserDetail(generics.RetrieveUpdateDestroyAPIView):
          permission_classes = [IsProfileOwnerOrReadOnly]
          serializer_class = UserSerializer
      
          def get_queryset(self):
              return UserDetail.objects.filter(pk=self.kwargs["pk"])
      

      如果您需要另一个示例,请查看此主题:Django 2.0 url parameters in get_queryset

      编辑:在这两种情况下,将您的 UserSerializer 更改为:

      class UserSerializer(serializers.ModelSerializer):
          courses = serializers.PrimaryKeyRelatedField(
              many=True, read_only=True)
          class Meta:
              model = User
              fields = ['id', 'username', 'courses']
      

      【讨论】:

      • 这不起作用,它只获取一个用户的详细信息,但是当我使用可浏览的 api 时,我仍然看到 put 请求的每门课程。我认为问题出在序列化程序中的课程变量上,但我不知道如何只获取用户课程而不是所有课程。
      • 确实,您的序列化程序有参数queryset=Course.objects.all()。尝试删除此参数并设置read_only=True
      猜你喜欢
      • 1970-01-01
      • 2018-05-21
      • 2020-05-15
      • 1970-01-01
      • 2019-11-27
      • 2021-01-10
      • 2016-07-17
      • 1970-01-01
      • 2017-08-19
      相关资源
      最近更新 更多