Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 如何使用基于类的视图处理表单(通过get或post)?_Django_Django Class Based Views - Fatal编程技术网

Django 如何使用基于类的视图处理表单(通过get或post)?

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

我正在尝试学习基于类的视图,因为细节视图或列表视图并没有那么复杂

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

这是函数代码(不是我的,来自django的书):

忽略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
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。这将一直持续到更多用户交互发生。我可以用这种方法将generic
ListView
FormView
组合在一个页面上吗?这样我就可以将数据库中的记录列表和表单都放在一个模板上只需将
ListView
类替换为
FormView
,然后重写
get
方法不起作用,只有表单作为上下文传递,视图作为
传递