问题描述
我试图学习基于类的视图,因为详细视图或列表视图并不那么复杂。
Im trying to learn class-based views, for a detail or list view is not that complicated.
我有一个搜索表单,我只想看看是否我发送查询以显示结果。
I have a search form and I just want to see if I send a query to show up the results.
这是函数代码(不是我的,是从django的书中获得的):
Here is the function code (is not mine, is from a django book):
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事实(只是为了使问题现在更简单) ,如何将其转换为基于类的视图?
Ignoring the ajax fact (just to make the problem easier for now), how can I translate this to class-based views?
我快速尝试了以下操作:
I quick tried something like this:
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'对象不可调用
Doesn't work, I get a: "'NoneType' object is not callable"
足够,我今天开始介绍这种东西。
Fair enough, I started today with this stuff.
那么,基于类的视图可以管理get(如果需要,也可以发布)请求的方式是什么?
So, what's the way to make a Class-based views that can manage a get (and a post too if needed) request?
我有另一个例子:
@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()
这是否会像第一个一样转换一?还是他们扩展了不同的观点?
Would this be "transformed" the same way that the first one? Or they extend differents Views?
我很困惑。我不知道第一个是ProcessFormView,第二个是FormView还是什么。
Im confused a lot. I don't know if the first is ProcessFormView and the second FormView or what.
谢谢。
编辑:解决方案我以:
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
我将其留给有相同问题的人:)
I leave this here to someone with same question :)
推荐答案
类用于显示 GET
请求的未绑定表单,并绑定 POST
的表单(或 PUT
)请求。如果绑定的格式有效,则调用 form_valid
方法,该方法仅重定向到成功网址(由 success_url $ c $定义) c>属性或
get_success_url
方法。
The default behaviour of the FormView
class is to display an unbound form for GET
requests, and bind the form for POST
(or PUT
) requests. If the bound form is valid, then the form_valid
method is called, which simply redirects to the success url (defined by the success_url
attribute or the get_success_url
method.
这与示例非常匹配,您需要覆盖 form_valid
方法创建新的 User
,然后调用超类方法重定向到成功URL。
This matches the example quite well. You need to override the form_valid
method to create the new User
, before calling the superclass method to redirect to the success url.
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
数据,并且在表单有效时您不会执行任何操作。
Your first example does not match the flow of FormView
so well, because you aren't processing a form with POST
data, and you don't do anything when the form is valid.
我可能会尝试扩展 TemplateView
,并将所有逻辑放入 get_context_data
。
一旦完成工作,就可以分解解析GET数据并将书签返回到其自己的方法中的代码。您可以查看扩展 ListView
的方法,但是除非您想对结果进行分页,否则我认为没有任何真正的优势。
I might try extending TemplateView
, and putting all the logic in get_context_data
.Once you get that working, you could factor the code that parses the GET data and returns the bookmarks into its own method. You could look at extending ListView
, but I don't think there's any real advantage unless you want to paginate results.
这篇关于如何使用基于类的视图处理表单(通过获取或发布)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!