首页 文章

在Django 1.6中结合DetailView和CreateView

提问于
浏览
3

我有2个独立的模型,帖子和评论 . 我使用DetailView显示Post内容,我想使用CreateView在同一页面上显示评论创建表单 . 最简洁的方法是什么?

我唯一想到的是使用自定义视图,它既可以获取对象,也可以处理注释表单,但这看起来太脏了:

def post_detail(request, slug):
    post = get_object_or_404(Post, slug=slug)
    if request.POST:
        form = CommentForm(request.POST)
        # do comment form processing here
    return render(request, "post/post_detail.html", {
        "object": post, "comment_form": form})

有没有干净的方法来使用基于类的视图?或者只是某种方式将后期显示代码与评论处理代码分离?

2 回答

  • 3

    一种选择是使用PostView的DetailView和模板标签来显示评论表单 . 让评论表单提交给评论CreateView,成功时重定向到DetailView .

    也就是说,如果表单无效,可能会有点难看 . 在紧要关头,您始终可以从其中一个CreateView方法调用DetailView或其方法 . 但IMO引入了更多的耦合而不是更少 . 或者您可以使用单独的实用程序函数,如果注释表单有错误,您可以从CreateView调用以显示Post .

    另一种选择是使用AJAX来处理注释表单(在单独的CreateView中)而不是新的页面加载 .

    最后,无论语言或框架如何,对于需要显示一个对象类型并创建另一个对象类型的视图可以解耦多少都是有限制的 .

  • 0

    可以组合 DetailViewCreateView . 您使用 DetailView 的类和 CreateView 的另一个类,然后创建一个继承自View的新类 . 这个新类有一个get和post方法 . get方法调用 DetailView ,而post方法调用 CreateView . 请注意在 CreateView 中对 success_url 使用reverse_lazy . 所以基本上你的代码应该是这样的:

    class PostView(DetailView):
        # your code 
        pass ;
    
    class CommentView(CreateView):
        def get_success_url(self):
        return reverse_lazy('post_detail', kwargs={'pk': self.get_object(Post.objects.all().pk})
    
        pass
    
    class PostCommentView(View):
        def get(self, request, *args, **kwargs):
             view = PostView.as_view()
             return view(request, *args, **kwargs) 
    
        def post(self, request, *args, **kwargs) :
             view = CommentView.as_view()
             return view(request, *args, **kwargs)
    

    所以你的urls.py会指向

    PostCommentView
    

    我对get_success_url进行了覆盖,因为它会尝试转到不存在的新注释的详细视图,而不是你想要做什么 . 因此覆盖将带您进入帖子的详细视图 .

    文档中有一个解释

    https://docs.djangoproject.com/en/2.0/topics/class-based-views/mixins/#an-alternative-better-solution

相关问题