我试图学习基于类的视图,对于细节或列表视图并不复杂。
我有一个搜索表单,我只想查看是否发送查询以显示结果。
这是功能代码(不是我的,来自django书):
def search_page(request):
form = SearchForm()
bookmarks = []
show_results = False
if 'query' in request.GET:
show_results = True
query = request.GET['query'].strip()
if query:
form = SearchForm({'query': query})
bookmarks = Bookmark.objects.filter(title__icontains=query)[:10]
show_tags = True
show_user = True
if request.is_ajax():
return render_to_response("bookmarks/bookmark_list.html", locals(), context_instance=RequestContext(request))
else:
return render_to_response("search/search.html", locals(), context_instance=RequestContext(request))
忽略ajax事实(现在只是为了使问题更容易),我该如何将其转换为基于类的视图?
我很快尝试了这样的事情:
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
不能工作,我得到了一个:"' NoneType'对象不可调用"
很公平,我今天开始用这些东西。
那么,制作基于类的视图的方法是什么,可以管理get(如果需要也可以发布帖子)请求?
我有另一个例子:
@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
我把这个留给有同样问题的人:)
答案 0 :(得分:26)
FormView
类的默认行为是显示GET
个请求的未绑定表单,并绑定POST
(或PUT
)个请求的表单。如果绑定表单有效,则调用form_valid
方法,该方法只会重定向到成功网址(由success_url
属性或get_success_url
方法定义。
这很好地匹配了这个例子。在调用超类方法重定向到成功URL之前,您需要覆盖form_valid
方法来创建新的User
。
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_context_data
中。
一旦你开始工作,你可以考虑解析GET数据的代码并将书签返回到自己的方法中。您可以考虑扩展ListView
,但我认为除非您想要对结果进行分页,否则没有任何实际优势。
答案 1 :(得分:8)
注意,这里的答案(Updating context data in FormView form_valid method?)解决了这个问题:
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)
这对我来说非常合适。 (与此问题中的问题相同)
如上所述,这不是我的解决方案,如果你想给某人一些学分,请转到链接中的答案并给予此人学分! (Updating context data in FormView form_valid method?)