Django 教程 9: 使用表单

您所在的位置:网站首页 borrowed的中文 Django 教程 9: 使用表单

Django 教程 9: 使用表单

#Django 教程 9: 使用表单| 来源: 网络整理| 查看: 265

正如上面的 Django 表单处理过程中,所讨论的那样,视图必须在首次调用时呈现默认表单,然后在数据无效时,重新呈现它,并显示错误消息,或者数据有效时,处理数据,并重定向到新页面。为了执行这些不同的操作,视图必须能够知道,它是第一次被调用以呈现默认表单,还是后续处理以验证数据。

对于使用POST 请求向服务器提交信息的表单,最常见的模式,是视图针对POST 请求类型进行测试(if requesthod == 'POST':) 以识别表单验证请求和GET (使用一个else 条件)来识别初始表单创建请求。如果要使用GET 请求提交数据,则识别这是第一个、还是后续视图调用的典型方法,是读取表单数据(例如,读取表单中的隐藏值)。

书本续借过程将写入我们的数据库,因此按照惯例,我们使用 POST 请求方法。下面的代码片段,显示了这种函数视图的(非常标准)模式。

from django.shortcuts import get_object_or_404 from django.http import HttpResponseRedirect from django.urls import reverse import datetime from .forms import RenewBookForm def renew_book_librarian(request, pk): book_inst=get_object_or_404(BookInstance, pk = pk) # If this is a POST request then process the Form data if requesthod == 'POST': # Create a form instance and populate it with data from the request (binding): form = RenewBookForm(request.POST) # Check if the form is valid: if form.is_valid(): # process the data in form.cleaned_data as required (here we just write it to the model due_back field) book_inst.due_back = form.cleaned_data['renewal_date'] book_inst.save() # redirect to a new URL: return HttpResponseRedirect(reverse('all-borrowed') ) # If this is a GET (or any other method) create the default form. else: proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3) form = RenewBookForm(initial={'renewal_date': proposed_renewal_date,}) return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})

首先,我们导入我们的表单(RenewBookForm)和视图函数中使用的许多其他有用的对象/方法:

get_object_or_404(): 根据模型的主键值,从模型返回指定的对象,如果记录不存在,则引发Http404 异常(未找到)。 HttpResponseRedirect: 这将创建指向指定 URL 的重定向(HTTP 状态代码 302)。 reverse(): 这将从 URL 配置名称和一组参数生成 URL。它是我们在模板中使用的 url 标记的 Python 等价物。 datetime: 用于操作日期和时间的 Python 库。

在视图中,我们首先使用 get_object_or_404()中的 pk 参数,来获取当前的 BookInstance (如果这不存在,视图将立即退出,页面将显示“未找到”错误)。如果这不是 POST 请求(由 else 子句处理),那么我们创建默认表单,传递 renewal_date 字段的initial 初始值(如下面的粗体所示,这是从当前日期起的 3 周)。

book_inst=get_object_or_404(BookInstance, pk = pk) # If this is a GET (or any other method) create the default form else: proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3) form = RenewBookForm(initial={'renewal_date': proposed_renewal_date,}) return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})

创建表单后,我们调用 render() 来创建 HTML 页面,指定模板和包含表单的上下文。在这种情况下,上下文还包含我们的 BookInstance,我们将在模板中使用它,来提供有关我们正在续借的书本信息。

但是,如果这是一个POST 请求,那么我们创建表单对象,并使用请求中的数据填充它。此过程称为“绑定”,并且允许我们验证表单。然后我们检查表单是否有效,它运行所有字段上的所有验证代码 - 包括用于检查我们的日期字段,实际上是有效日期的通用代码,以及用于检查日期的特定表单的clean_renewal_date()函数在合适的范围内。

book_inst=get_object_or_404(BookInstance, pk = pk) # If this is a POST request then process the Form data if requesthod == 'POST': # Create a form instance and populate it with data from the request (binding): form = RenewBookForm(request.POST) # Check if the form is valid: if form.is_valid(): # process the data in form.cleaned_data as required (here we just write it to the model due_back field) book_inst.due_back = form.cleaned_data['renewal_date'] book_inst.save() # redirect to a new URL: return HttpResponseRedirect(reverse('all-borrowed') ) return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})

如果表单无效,我们再次调用render() ,但这次在上下文中传递的表单值将包含错误消息。

如果表单有效,那么我们可以开始使用数据,通过 form.cleaned_data属性访问它(例如 data = form.cleaned_data['renewal_date'])。这里我们只将数据保存到关联的BookInstance 对象的due_back 值中。

警告: 虽然您也可以通过请求直接访问表单数据(例如request.POST['renewal_date'] 或 request.GET['renewal_date'](如果使用 GET 请求),但不建议这样做。清理后的数据是无害的、验证过的、并转换为 Python 友好类型。

视图的表单处理部分的最后一步,是重定向到另一个页面,通常是“成功”页面。在这种情况下,我们使用 HttpResponseRedirect 和 reverse() ,重定向到名为'all-borrowed'的视图(这是在 Django 教程第 8 部分中创建的“挑战”:用户身份验证和权限)。如果您没有创建该页面,请考虑重定向到 URL'/'处的主页。

这就是表单处理本身所需的一切,但我们仍然需要将视图,限制为图书馆员可以访问。我们应该在 BookInstance (“can_renew”)中创建一个新的权限,但为了简单起见,我们只需使用@permission_required函数装饰器,和我们现有的 can_mark_returned 权限。

因此,最终视图如下所示。请将其复制到 locallibrary/catalog/views.py 的底部。

from django.contrib.auth.decorators import permission_required from django.shortcuts import get_object_or_404 from django.http import HttpResponseRedirect from django.urls import reverse import datetime from .forms import RenewBookForm @permission_required('catalog.can_mark_returned') def renew_book_librarian(request, pk): """ View function for renewing a specific BookInstance by librarian """ book_inst=get_object_or_404(BookInstance, pk = pk) # If this is a POST request then process the Form data if requesthod == 'POST': # Create a form instance and populate it with data from the request (binding): form = RenewBookForm(request.POST) # Check if the form is valid: if form.is_valid(): # process the data in form.cleaned_data as required (here we just write it to the model due_back field) book_inst.due_back = form.cleaned_data['renewal_date'] book_inst.save() # redirect to a new URL: return HttpResponseRedirect(reverse('all-borrowed') ) # If this is a GET (or any other method) create the default form. else: proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3) form = RenewBookForm(initial={'renewal_date': proposed_renewal_date,}) return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3