Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django 1.6中DetailView和CreateView的组合_Python_Django_Django Class Based Views_Django Generic Views - Fatal编程技术网

Python Django 1.6中DetailView和CreateView的组合

Python Django 1.6中DetailView和CreateView的组合,python,django,django-class-based-views,django-generic-views,Python,Django,Django Class Based Views,Django Generic Views,我有两个独立的模型,帖子和评论。我使用DetailView显示文章内容,我想使用CreateView在同一页面上显示评论创建表单。最干净的方法是什么 我想到的唯一一件事是使用自定义视图,它既获取对象又处理注释表单,但这看起来太脏了: def post_detail(request, slug): post = get_object_or_404(Post, slug=slug) if request.POST: form = CommentForm(request

我有两个独立的模型,帖子和评论。我使用DetailView显示文章内容,我想使用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})

使用基于类的视图有什么干净的方法可以做到这一点吗?或者只是某种将帖子显示代码与评论处理代码分离的方法?

一个选项是使用帖子的DetailView和templatetag来显示评论表单。让注释表单提交到注释CreateView,成功后重定向到DetailView

也就是说,如果表单无效,它可能会变得有点难看。在紧急情况下,您始终可以从CreateView方法之一调用DetailView或其方法。但IMO认为,这引入了更多的耦合,而不是更少的耦合。或者,您可以使用一个单独的实用程序函数,如果注释表单有错误,您可以从CreateView调用该函数来显示帖子

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


最后,无论使用何种语言或框架,对需要显示一种对象类型并创建另一种对象类型的视图进行解耦的程度都是有限的。

可以将
DetailView
CreateView
结合起来。您为
DetailView
使用一个类,为
CreateView
使用另一个类,然后创建从视图继承的新类。这个新类有一个get和post方法。get方法调用
DetailView
,而post方法调用
CreateView
。请注意在
CreateView
中为
success\u url
使用reverse\u 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})

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) 
因此,您的url.py将指向

PostCommentView 
我重写了
get\u success\u url
,因为它将尝试转到新注释的详细视图,该视图不存在,并且不是您想要做的。因此,覆盖将带您进入帖子的DetailView


在.

中有一个解释,这个视图有什么不好的地方?如果您将
GET
POST
混合在一起,请尝试
django.views.generic.base.View
。或者创建templatetags来为对象生成注释表单(比如以前使用的old
django.contrib.comments
)@kroolik最糟糕的是,我的注释和发布模型逻辑没有解耦。不过我确实喜欢templatetags的想法。这样我就可以有单独的视图来创建评论了。你可以看到它是如何完成的AJAX有点太糟糕了,但是模板标签是我的解决方案。我在这里使用了一个想法:(感谢@kroolik)。下面是我在最后所做的:我喜欢这个解决方案——它甚至可以进一步推广到任何需要在另一个DetailView中编辑的模型。所以现在我很好奇:你是如何处理评论表单无法验证的情况的?我将用户带到单独的页面,在那里她/他可以编辑评论:。但不使用AJAX只是个人的选择,这种选择没有错——我过去也曾这样做过。我还喜欢优雅的降级:即使您最终添加了AJAX,能够处理用户禁用javascript的情况也是很有价值的。@RuslanOsipov您提供的前两个链接不再可用。