【问题标题】:Convert DetailView to APIView in Django在 Django 中将 DetailView 转换为 APIView
【发布时间】:2020-11-08 15:47:03
【问题描述】:

我正在将 Django 转换为 Django REST API。现在我在 APIView 中遇到 self.object 错误。如何在 APIView 中使用 self.object 或替代选项?

这是我的 DetailView...

class ChapterDetail(DetailView):
    model= Chapter
    context_object_name = 'chapter'

    def get_context_data(self, **kwargs):
        context = super(ChapterDetail, self).get_context_data(**kwargs)
        user = self.request.user
        user_practice_game = UserPracticeGame.objects.filter(user=user).filter(practice_game__chapter=self.object).first()
   
        context['user_practice_game'] = user_practice_game

        return context

这是我的 APIView...

class ChapterDetailAPIView(APIView): # need review
    def get(self, request, *args, **kwargs):
        context = {}
        qs_user_practice_game = UserPracticeGame.objects.filter(user=self.request.user).filter(practice_game__chapter=
        upg_serializer = UserPracticeGame(qs_user_practice_game, many=True)
        context['user_practice_game'] = upg_serializer.data
        return Response(context, status=200)

在 APIView 中,我无法在查询中使用 practice_game__chapter=self.object

这是我的模特...

class UserPracticeGame(DateMixin, models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='User', related_name='user_practice_game')
    practice_game = models.ForeignKey(PracticeGame, on_delete=models.CASCADE, verbose_name='Practice Game', related_name='user_practice_game')
    total_answered = models.IntegerField(verbose_name='Total Answered', default=0, blank=True, null=True)

【问题讨论】:

    标签: django api django-models django-rest-framework django-views


    【解决方案1】:

    DetailView提供了一个名为get_object()的成员方法,负责提供对应的对象(我们从self.object得到的对象)。

    使用来自 drf 的 GenericAPIView 而不是 APIView。它提供了相同的get_object() 方法,因此您可以访问该对象。这应该可以解决您的问题。

    class ChapterDetailAPIView(GenericAPIView):
        queryset = Chapter.objects.all()
        serializer_class = ChapterSerializer # you need a serializer for Chapter
        def get(self, request, *args, **kwargs):
            context = {}
            curr_obj = self.get_object()
            qs_user_practice_game = UserPracticeGame.objects.filter(user=self.request.user).filter(practice_game__chapter=curr_obj)
            upg_serializer = UserPracticeGame(qs_user_practice_game, many=True)
            context['user_practice_game'] = upg_serializer.data
            return Response(context, status=200)
    

    有关GenericAPIView 的更多信息,请关注 drf documentation

    【讨论】:

    • 你好@mursalin,在尝试了你的方式之后,现在我面临着......“AssertionError:'ChapterDetailAPIView'应该包含一个查询集属性,或者覆盖get_queryset()方法。”那么,我应该怎么做才能克服呢?感谢您的帮助。
    • @MinhajulIslam,我已经更新了答案。 GenericAPIView 更多是用于通用目的,因此您必须为其添加一些属性,您也可以检查RetriveAPIView。不要指望答案会按原样工作,答案会指引你走向正确的方向。请检查我提供的文档链接。
    猜你喜欢
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 2019-08-19
    • 2012-03-13
    • 2021-10-15
    • 1970-01-01
    相关资源
    最近更新 更多