[英]Django: WARNING - Method Not Allowed (POST)
I know what above error means.我知道上面的错误意味着什么。 Seems I can't handle form when it is posted.当它发布时,我似乎无法处理表格。 I can do it in function based views, but in class based views I am tad lost.我可以在基于函数的视图中做到这一点,但在基于类的视图中我有点迷失了。
I am creating a comment app and here is forms.py
content in comment
app:我正在创建一个评论应用程序,这里是comment
应用程序中的forms.py
内容:
class CommentForm(forms.Form):
content_type = forms.CharField(widget=forms.HiddenInput)
object_id = forms.CharField(widget=forms.HiddenInput)
body = forms.CharField(widget=forms.Textarea)
then in DetailView
of the blog app, I handled it this way:然后在博客应用程序的DetailView
中,我是这样处理的:
class BlogDetail(DetailView):
model = Blog
template_name = 'blogs/blog_detail.html'
context_object_name = 'blog'
def get_object(self):
blog_slug = self.kwargs.get('blog_slug')
return get_object_or_404(Blog, slug=blog_slug)
def get_context_data(self, *args, **kwargs):
obj = self.get_object()
context = super().get_context_data(**kwargs)
context['comments'] = Comment.objects.filter_by_instance(obj)
""" comment form """
initial_data = {
'content_type': obj.get_content_type,
'object_id': obj.id
}
if self.request.method == 'POST':
form = CommentForm(self.request.POST, initial=initial_data)
if form.is_valid():
c_type = form.cleaned_data.get('content_type')
content_type = ContentType.objects.get(model=c_type)
object_id = form.cleaned_data.get('object_id')
body = form.cleaned_data.get('body')
new_comment, created = Comment.objects.get_or_create(
user=self.request.user,
content_type=content_type,
object_id=object_id,
body=body
)
else:
form = CommentForm(initial=initial_data)
context['comment_form'] = form
return context
albeit I passsed form = CommentForm(self.request.POST, initial=initial_data)
but there sounds something is going wrong, Can anyone help?尽管我通过了form = CommentForm(self.request.POST, initial=initial_data)
但听起来有些问题,有人可以帮忙吗? Thank you谢谢
edited:编辑:
class BlogDetail(DetailView, FormView):
model = Blog
template_name = 'blogs/blog_detail.html'
context_object_name = 'blog'
form_class = CommentForm
def get_object(self):
blog_slug = self.kwargs.get('blog_slug')
return get_object_or_404(Blog, slug=blog_slug)
def get_initial(self):
obj = self.get_object()
return {
'content_type': obj.get_content_type,
'object_id': obj.id
}
def form_valid(self, form):
c_type = form.cleaned_data.get('content_type')
content_type = ContentType.objects.get(model=c_type)
object_id = form.cleaned_data.get('object_id')
body = form.cleaned_data.get('body')
Comment.objects.create(
user=self.request.user,
content_type=content_type,
object_id=object_id,
body=body
)
edit 2:编辑2:
Can anyone spot the error with this approach:任何人都可以通过这种方法发现错误:
class BlogDetail(DetailView):
model = Blog
template_name = 'blogs/blog_detail.html'
context_object_name = 'blog'
form_class = CommentForm
def get_object(self):
blog_slug = self.kwargs.get('blog_slug')
return get_object_or_404(Blog, slug=blog_slug)
def get(self, request, *args, **kwargs):
obj = self.get_object()
initial_data = {
'content_type': obj.get_content_type,
'object_id': obj.id
}
print("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa", obj.get_content_type)
form = self.form_class(initial=initial_data)
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
c_type = form.cleaned_data.get('content_type')
content_type_2 = ContentType.objects.get(model=c_type)
object_id = form.cleaned_data.get('object_id')
body = form.cleaned_data.get('body')
Comment.objects.create(
user=request.user,
content_type=content_type_2,
object_id=object_id,
body=body,
)
return render(request, self.template_name, {'form': form})
Posts are handled by the post
method of the class-based view:帖子由基于类的视图的post
方法处理:
class BlogDetail(DetailView):
# ...
def post(self, request, *args, **kwargs):
# all your form processing
Django ships with several views, that already provide various hooks into the form handling process, eg FormView
, that you could leverage instead: Django 附带了几个视图,它们已经为表单处理过程提供了各种挂钩,例如FormView
,您可以利用它们:
class BlogDetail(DetailView, FormView):
form_class = CommentForm
def form_valid(self, form):
c_type = form.cleaned_data.get('content_type')
# ...
def get_initial(self):
obj = self.get_object()
return {
'content_type': obj.get_content_type,
'object_id': obj.id
}
# ....
By default, the form is passed as "form"
into the context.默认情况下,表单作为"form"
传递到上下文中。
To allow post requests to your view, write a function def post(self, request, *args, **kwargs)
which will receive the post request.要允许向您的视图发送请求,请编写一个函数def post(self, request, *args, **kwargs)
来接收发布请求。 If you want to handle this as you would handle get, redirect it to the get function如果您想像处理 get 一样处理此问题,请将其重定向到 get 函数
def post(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
You don't need the DetailView
.您不需要DetailView
。 You can simply use CreateView.您可以简单地使用 CreateView。 I think you have everything overridden correctly to be able to ditch DetailView, except maybe get_form_kwargs().我认为您已经正确覆盖了所有内容以便能够放弃 DetailView,除了 get_form_kwargs()。
However...然而...
I usually approach this differently, cause it's confusing and very hacky.我通常以不同的方式处理这个问题,因为它令人困惑且非常hacky。 Instead, you add the form via get_context_data() to the DetailView and then in the template post to /blog/{id}/comment/create
, where you have the CreateView.相反,您通过 get_context_data() 将表单添加到 DetailView,然后在模板 post 中添加到/blog/{id}/comment/create
,在那里您拥有 CreateView。 That makes things a lot simpler.这让事情变得简单了很多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.