Django 如何使用基于类的视图处理表单(通过get或post)?
我正在尝试学习基于类的视图,因为细节视图或列表视图并没有那么复杂 我有一个搜索表单,我只是想看看我是否发送了一个查询来显示结果 这是函数代码(不是我的,来自django的书): 忽略ajax事实(只是为了让问题变得更简单),如何将其转换为基于类的视图 我很快就试过这样的方法:Django 如何使用基于类的视图处理表单(通过get或post)?,django,django-class-based-views,Django,Django Class Based Views,我正在尝试学习基于类的视图,因为细节视图或列表视图并没有那么复杂 我有一个搜索表单,我只是想看看我是否发送了一个查询来显示结果 这是函数代码(不是我的,来自django的书): 忽略ajax事实(只是为了让问题变得更简单),如何将其转换为基于类的视图 我很快就试过这样的方法: class SearchPageView(FormView): template_name = 'search/search.html' def get(self, request, *args, **k
class SearchPageView(FormView):
template_name = 'search/search.html'
def get(self, request, *args, **kwargs):
form = SearchForm()
self.bookmarks = []
self.show_results = False
if 'query' in self.request.GET:
self.show_results = True
query = self.request.GET['query'].strip()
if query:
form = SearchForm({'query': query})
self.bookmarks = Bookmark.objects.filter(title__icontains=query)[:10]
return super(SearchPageView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(SearchPageView, self).get_context_data(**kwargs)
context.update({
'show_tags': True,
'show_user': True,
'show_results': self.show_results,
'bookmarks': self.bookmarks
})
return context
class ContextFormView(FormView):
template_name = 'some_template.html'
success_url = '...'
form_class = ClassOfTheForm
def get(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
context = self.get_context_data(**kwargs)
context['form'] = form
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
if form.is_valid():
return self.form_valid(form, **kwargs)
else:
return self.form_invalid(form, **kwargs)
def form_invalid(self, form, **kwargs):
context = self.get_context_data(**kwargs)
context['form'] = form
# here you can add things like:
context[show_results] = False
return self.render_to_response(context)
def form_valid(self, form, **kwargs):
context = self.get_context_data(**kwargs)
context['form'] = form
# here you can add things like:
context[show_results] = True
return self.render_to_response(context)
不起作用,我得到一个:“'NoneType'对象不可调用”
很公平,我今天从这件事开始
那么,如何创建一个基于类的视图来管理get(如果需要,还可以管理post)请求呢
我还有一个例子:
@render_to('registration/register.html')
def register_page(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
user = User.objects.create_user(
username=form.cleaned_data['username'],
password=form.cleaned_data['password1'],
email=form.cleaned_data['email']
)
return HttpResponseRedirect('/accounts/register/success/')
else:
form = RegistrationForm()
return locals()
这会像第一个一样被“改造”吗?或者他们扩展了不同的观点
我很困惑。我不知道第一个是ProcessFormView,第二个是FormView还是什么
谢谢
编辑:解决方案我以以下内容结束:
class SearchPageView(FormView):
template_name = 'search/search.html'
def get(self, request, *args, **kwargs):
self.bookmarks = []
self.show_results = False
form = SearchForm(self.request.GET or None)
if form.is_valid():
self.show_results = True
self.bookmarks = Bookmark.objects.filter(title__icontains=form.cleaned_data['query'])[:10]
return self.render_to_response(self.get_context_data(form=form))
def get_context_data(self, **kwargs):
context = super(SearchPageView, self).get_context_data(**kwargs)
context.update({
'show_tags': True,
'show_user': True,
'show_results': self.show_results,
'bookmarks': self.bookmarks
})
return context
我把这个问题留给有同样问题的人:)类的默认行为是为
GET
请求显示未绑定的表单,并为POST
(或PUT
)请求绑定表单。如果绑定的表单有效,则调用form\u valid
方法,该方法仅重定向到成功url(由success\u url
属性或get\u success\u url
方法定义)
这与示例非常匹配。在调用超类方法重定向到成功url之前,需要重写form\u valid
方法来创建新的用户
class CreateUser(FormView):
template_name = 'registration/register.html'
success_url = '/accounts/register/success/'
form_class = RegistrationForm
def form_valid(self, form):
user = User.objects.create_user(
username=form.cleaned_data['username'],
password=form.cleaned_data['password1'],
email=form.cleaned_data['email']
)
return super(CreateUser, self).form_valid(form)
您的第一个示例与FormView
的流程不太匹配,因为您没有处理包含POST
数据的表单,并且当表单有效时,您没有执行任何操作
我可以尝试扩展TemplateView
,并将所有逻辑放在get\u context\u data
中。
一旦你开始工作,你可以将解析get数据并返回书签的代码分解成它自己的方法。你可以考虑扩展ListView
,但我认为没有任何真正的优势,除非你想对结果进行分页。注意,这里的答案()解决了这个问题,如下所示:
class SearchPageView(FormView):
template_name = 'search/search.html'
def get(self, request, *args, **kwargs):
form = SearchForm()
self.bookmarks = []
self.show_results = False
if 'query' in self.request.GET:
self.show_results = True
query = self.request.GET['query'].strip()
if query:
form = SearchForm({'query': query})
self.bookmarks = Bookmark.objects.filter(title__icontains=query)[:10]
return super(SearchPageView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(SearchPageView, self).get_context_data(**kwargs)
context.update({
'show_tags': True,
'show_user': True,
'show_results': self.show_results,
'bookmarks': self.bookmarks
})
return context
class ContextFormView(FormView):
template_name = 'some_template.html'
success_url = '...'
form_class = ClassOfTheForm
def get(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
context = self.get_context_data(**kwargs)
context['form'] = form
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
if form.is_valid():
return self.form_valid(form, **kwargs)
else:
return self.form_invalid(form, **kwargs)
def form_invalid(self, form, **kwargs):
context = self.get_context_data(**kwargs)
context['form'] = form
# here you can add things like:
context[show_results] = False
return self.render_to_response(context)
def form_valid(self, form, **kwargs):
context = self.get_context_data(**kwargs)
context['form'] = form
# here you can add things like:
context[show_results] = True
return self.render_to_response(context)
这对我来说效果很好。(与此问题中的问题相同)
如上所述,这不是我的解决方案,如果您想给某人积分,请转到链接中的答案并给此人积分!()复制和粘贴'NoneType'对象是不可调用的“
没有多大帮助。如果你查看回溯中的行号,你可以看到哪行代码引发了异常,这可能有助于你自己修复异常。问题更新,你是对的,我不得不上床睡觉,我认为我需要指定我的表单类,是的,你是对的。在本例中效果很好(更改属性的名称:P)但我仍然认为第一个示例需要一个正确的基于类的视图表示法。请您在这里帮助我。当您定义用户对象时,它在form_valid method之后会去哪里,这对我来说很神奇。@skzd我恐怕不明白您的意思。除非我上面的回答有错误,请打开一个新的问题,而不是一个新的问题在此处添加注释。@skzd,在form\u valid运行后,函数退出,页面重定向到success\u url。这将一直持续到更多用户交互发生。我可以用这种方法将genericListView
和FormView
组合在一个页面上吗?这样我就可以将数据库中的记录列表和表单都放在一个模板上只需将ListView
类替换为FormView
,然后重写get
方法不起作用,只有表单作为上下文传递,视图作为
传递