django - 如何使用基于类的 View 处理表单(通过 get 或 post)?

标签 django django-class-based-views

我正在尝试学习基于类的 View ,因为详细信息或 ListView 并不那么复杂。

我有一个搜索表单,我只想看看我是否发送查询以显示结果。

这是函数代码(不是我的,来自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 事实(现在只是为了让问题更简单),我如何将其转换为基于类的 View ?

我很快尝试了这样的事情:

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' 对象不可调用”

很公平,我今天从这些东西开始。

那么,创建可以管理获取(如果需要也可以发布)请求的基于类的 View 的方法是什么?

我还有一个例子:

@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()

这会像第一个一样“转换”吗?或者他们扩展了不同的 View ?

我很困惑。我不知道第一个是 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

我把这个留给有同样问题的人:)

最佳答案

FormView 的默认行为类是为GET请求显示未绑定(bind)的表单,为POST(或PUT)请求绑定(bind)表单。如果绑定(bind)表单有效,则调用 form_valid 方法,该方法简单地重定向到成功 url(由 success_url 属性或 get_success_url 方法。

这与示例非常吻合。您需要覆盖 form_valid 方法来创建新的 User,然后调用父类(super class)方法重定向到成功 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 数据的表单,并且当表格有效。

我可能会尝试扩展 TemplateView,并将所有逻辑放在 get_context_data 中。 一旦你开始工作,你就可以分解解析 GET 数据并将书签返回到它自己的方法中的代码。您可以考虑扩展 ListView,但我认为除非您想对结果进行分页,否则没有任何真正的优势。

关于django - 如何使用基于类的 View 处理表单(通过 get 或 post)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8903601/

相关文章:

django - Virtualbox guest 端口转发问题上的 Win7 主机和 Ubuntu 服务器

python - Django - 在不访问数据库的情况下访问外键值

python - 如何为基于类的 View 创建分页器?

Django - 在基于类的 View 中添加行到表单集,无需使用 javascript

django - 我无法更新 Django 的 RedirectView。它一直引用状态为 301 Moved Permenantly 的旧 URL

jQuery AJAX,json数据成为Django中的关键,无法解析数据

Django Rest 更改 URL 中的主键以使用自定义键

基于 Django 类的 View 复合

Django CBV : Easy access to url parameters in get_context_data()?

django - 使用 .only() 比使用 .values() 慢多少?