验证实例是否存在django

时间:2020-07-30 12:47:43

标签: django django-rest-framework

我正在DRF上构建REST Api。我有一个来自rest_framework.viewsets的ModelViewSet端点。

我有一个帖子和一个评论模型。每个评论都属于一个帖子。所以我定义了2个端点,

1) router.register(r"posts", views.PostView
2) router.register(r"(?P<pk>[^/.]+)/comments", views.CommentView

它们都继承自ModelViewSet,因此我可以对它们执行CRUD操作。

我对第二个终点有疑问。由于我们创建了对帖子的评论,因此我从posts / int:pk / comments获得了帖子pk。但是问题是当我在此端点上执行GET请求时,它将返回所有评论的列表,但是我需要那些评论属于帖子(URL中的id)。当我尝试在此端点上发出POST请求(如果该帖子不存在)时,会引发“ DosNotExist”错误,这是合乎逻辑的。

到目前为止,我所做的是:

  1. 重新定义了一个get_queryset()以仅检索属于特定帖子的对象。如果该帖子不存在,则返回一个空列表(尽管我认为应该提高404)
  2. 在我的序列化程序中重新定义了validate(),以检查该帖子是否存在。如果不是,则返回404

但是当我在posts / int:pk / comments / int:pk上检查PUT,DELETE,PATCH方法时,也不会考虑post实例,即,即使post不存在,它也将允许这些操作我相信哪个错误。

ModelViewSet类中是否有一个方法可以在每个请求上触发并检查post实例是否存在?这样我就不必重新定义每个CRUD方法就可以了。

编辑

CommentView

class CommentView(ModelViewSet):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer
    lookup_url_kwarg = 'pk2'

    def get_queryset(self):
        queryset = Comment.objects.filter(post=self.kwargs.get('pk'))
        return queryset

    def perform_create(self, serializer, **kwargs):
        post = get_object_or_404(Post, pk=self.kwargs.get('pk'))
        serializer.save(author=self.request.user, post=post)

1 个答案:

答案 0 :(得分:0)

也许看看drf-nested-routers package

如果不能解决您的问题,也许您想要的是标准路由器注册:

router.register(r"posts", views.PostView)
router.register(r"comments", views.CommentView)

,然后在列出注释时使用django-filter之类的包通过查询参数进行过滤:/comments/?post=<id>。创建评论时,只需在请求的正文中发送帖子ID(别忘了在CommentSerializer中包含“ post”字段)

相关问题