如何使用基于类的视图处理表单(通过获取或发布)? [英] How to process a form (via get or post) using class-based views?

查看:46
本文介绍了如何使用基于类的视图处理表单(通过获取或发布)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图学习基于类的视图,因为详细视图或列表视图并不那么复杂。

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 :)

推荐答案

FormView 类用于显示 GET 请求的未绑定表单,并绑定 POST 的表单(或 PUT )请求。如果绑定的格式有效,则调用 form_valid 方法,该方法仅重定向到成功网址(由 success_url 属性或 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.

这篇关于如何使用基于类的视图处理表单(通过获取或发布)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆