django入门-表单-part4
尊重作者的劳动,转载请注明作者及原文地址 http://www.cnblogs.com/txwsqk/p/6514113.html
完全翻译自官方文档 https://docs.djangoproject.com/en/1.10/intro/tutorial04/
本节内容讲表单
让我们更新一下pools/detail.html,添加html表单的展示
- <h1>{{ question.question_text }}</h1>
- {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
- <form action="{% url 'polls:vote' question.id %}" method="post">
- {% csrf_token %}
- {% for choice in question.choice_set.all %}
- <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
- <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
- {% endfor %}
- <input type="submit" value="Vote" />
- </form>
解释一下上面的代码:
form里添加了一个radio单选框,label是单选框的标签,每个单选框的值是 choice.id,当你点了"submit"提交表单时,实际提交的内容是
一个变量choice=choice.id 即 input的name和value,表单提交的方法必须是post
forloop.counte是for循环的一个计数器,表示循环了多少次
{% csrf_token %}
这个是用来防止跨站攻击的,django已经帮我们做好了,放在form上就可以了
提交这个表单时,匹配的url是这个
- url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
现在更新一下我们的vote的视图
- from django.shortcuts import get_object_or_404, render
- from django.http import HttpResponseRedirect, HttpResponse
- from django.urls import reverse
- from .models import Choice, Question
- # ...
- def vote(request, question_id):
- question = get_object_or_404(Question, pk=question_id)
- try:
- selected_choice = question.choice_set.get(pk=request.POST['choice'])
- except (KeyError, Choice.DoesNotExist):
- # Redisplay the question voting form.
- return render(request, 'polls/detail.html', {
- 'question': question,
- 'error_message': "You didn't select a choice.",
- })
- else:
- selected_choice.votes += 1
- selected_choice.save()
- # Always return an HttpResponseRedirect after successfully dealing
- # with POST data. This prevents data from being posted twice if a
- # user hits the Back button.
- return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
解释request.POST 你用post提交表单时传的参数就是用这个接收,是一个字典类型的;对应的request.GET就是接收get请求的参数
- request.POST['choice']当key不存在时,会抛一个KeyError异常,所以代码要捕获这个异常
HttpResponseRedirect(url)当成功提交表单返回结果时就用这个函数
reverse这个函数是为了避免url的硬编码,本来这个url应该是这样的- url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
现在呢
- reverse('polls:results', args=(question.id,) 看不明白的请去复习上一节的内容(urls.py里的app_name和url()里的name就是这个用处
现在来完成result的视图
- from django.shortcuts import get_object_or_404, render
- def results(request, question_id):
- question = get_object_or_404(Question, pk=question_id)
- return render(request, 'polls/results.html', {'question': question})
result的视图有了,下面写展示的模板
- <h1>{{ question.question_text }}</h1>
- <ul>
- {% for choice in question.choice_set.all %}
- <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
- {% endfor %}
- </ul>
- <a href="{% url 'polls:detail' question.id %}">Vote again?</a>
这个例子就是你选择单选按钮,然后点击提交按钮,跳转到一个新的页面,没有使用ajax.
注意:
vote视图这里有并发问题,当多个人对同一个question投票时,数据库在存和取时就有资源竞争问题了
django的解决方案在此 https://docs.djangoproject.com/en/1.10/ref/models/expressions/#avoiding-race-conditions-using-f
厉害的来了
通用视图
考虑一下我们前面写的视图detail(),results(),index()都是web开发中最通用的操作,根据url的参数从数据库存取内容,然后模板展示,这就是django通用视图考虑的问题,下面让我们用通用视图修改一下我们前面的应用pools
先修改urls.py
- from django.conf.urls import url
- from . import views
- app_name = 'polls'
- urlpatterns = [
- url(r'^$', views.IndexView.as_view(), name='index'),
- url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
- url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
- url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
- ]
修改视图views.py
- from django.shortcuts import get_object_or_404, render
- from django.http import HttpResponseRedirect
- from django.urls import reverse
- from django.views import generic
- from .models import Choice, Question
- class IndexView(generic.ListView):
- template_name = 'polls/index.html'
- context_object_name = 'latest_question_list'
- def get_queryset(self):
- """Return the last five published questions."""
- return Question.objects.order_by('-pub_date')[:5]
- class DetailView(generic.DetailView):
- model = Question
- template_name = 'polls/detail.html'
- class ResultsView(generic.DetailView):
- model = Question
- template_name = 'polls/results.html'
- def vote(request, question_id):
- ... # same as above, no changes needed.
这里我们用了两个新的视图ListView和DetailView
ListView 展示成列表
DetailView 根据不同的model展示不同的详情页
这两个视图都需要一个叫model的属性,它得知道根据那个model展示相应的内容
DetailView通用视图是根据url中的的pk参数来获取数据库内容的,所以我们urls.py做了相应修改
这两个通用视图如果你不传template_name那么会使用默认的模板文件
DetailView使用<app name>/<modelname>_detail.html 本应用中就是 "polls/question_detail.html"
ListView使用<app name>/<modelname>_list.html ,当然你传了template_name它就用你定义的模板了
在前面的章节中我们可以给urls.py里定义的url()定义一个context字典来给view()传参数,通用视图有预定义的变量可以使用
DetailView使用model的小写作为context变量的key
ListView使用model的小写+_list作为context的key
当然你想使用自己的context可以传context_object_name来自定义你的context
更多通用视图的内容请参考 https://docs.djangoproject.com/en/1.10/topics/class-based-views/
本节完
django入门-表单-part4的更多相关文章
- python运维开发(十九)----Django后台表单验证、session、cookie、model操作
内容目录: Django后台表单验证 CSRF加密传输 session.cookie model数据库操作 Django后台Form表单验证 Django中Form一般有2种功能: 1.用于做用户提交 ...
- django form表单验证
一. django form表单验证引入 有时时候我们需要使用get,post,put等方式在前台HTML页面提交一些数据到后台处理例 ; <!DOCTYPE html> <html ...
- django from表单验证
django from表单验证 实现:表单验证 工程示例: urls.py 1 2 3 4 5 6 7 8 9 from django.conf.urls import url from djan ...
- django Form表单的使用
Form django表单系统中,所有的表单类都作为django.forms.Form的子类创建,包括ModelForm 关于django的表单系统,主要分两种 基于django.forms.Form ...
- Django(5) session登录注销、csrf及中间件自定义、django Form表单验证(非常好用)
一.Django中默认支持Session,其内部提供了5种类型的Session供开发者使用: 数据库(默认) 缓存 文件 缓存+数据库 加密cookie 1.数据库Session 1 2 3 4 5 ...
- django创建表单以及表单数据类型和属性
08.15自我总结 关于django的表单不同关系之间的创建 一.不同关系之间的创建 1.一对一 举例 母表:userinfo id name age 1 张三 12 2 李四 58 字表:priva ...
- Django form表单 组件
目录 Django form表单 组件 Form 组件介绍 普通方式手写注册功能 使用form组件实现注册功能 Form 常用字段与插件 常用字段(必备) 字段参数(必备) 内置验证(必备) 自定义效 ...
- [转]django自定义表单提交
原文网址:http://www.cnblogs.com/retop/p/4677148.html 注:本人使用的Django1.8.3版本进行测试 除了使用Django内置表单,有时往往我们需要自定义 ...
- Django实现表单验证、CSRF、cookie和session、缓存、数据库多表操作(双下划綫)
通常验证用户输入是否合法的话,是前端js和后端共同验证的,这是因为前端js是可以被禁用的,假如被禁用了,那就没法用js实现验证合法与否了,也就是即使用户输入的不合法,但是也没提示,用户也不知道怎么输入 ...
随机推荐
- go_goroutine and channel
协程Coroutine 轻量级”线程“ 非抢占式多任务处理,由协程主动交出控制权(如果程序中间没有print,程序会一直霸占着调度器) 编译器/解释器/虚拟机层面的多任务 多个协程可能在一个或多个线程 ...
- 9-eclispe中右键BuildPath没有了
Eclipse 右上角的代码视图,选择Java就好了!
- ASP.NET文件上传大小限制
上传限制 我们以为的文件大小限制 我们大家都知道ASP.NET为我们提供了文件上传服务器控件FileUpload,默认情况下可上传的最大文件为4M,如果要改变可上传文件大小限制,那么我们可以在web. ...
- c语言蛋疼的字符串赋值
我觉得c语言比较蛋疼的一个地方就是给字符串赋值,不是初始化,是赋值. char string[20]={0}; 你不能通过 string="hello";这种方式赋值.但是在字符串 ...
- JavaScript RegExp.test() 方法
定义和用法: test() 方法用于检测一个字符串是否匹配某个模式. 语法: RegExpObject.test(string); RegExpObject:正则表达式; string:必须参数,要检 ...
- Debian 如何使用测试版更新软件包到最新的版本
#vim /etc/apt/sources.list 将版本代号替换成 testing 然后更新,应可以安装最新的软件包了.
- 【转】Defunct进程 僵尸进程
在测试基于 DirectFB+Gstreamer 的视频联播系统的一个 Demo 的时候,其中大量使用 system 调用的语句,例如在 menu 代码中的 system("./play&q ...
- redis windows下安装
1.下载redis windows文件包 下载地址 2.解压文件包 复制压缩包地址 3.进入cmd 命令行 cd进入redis文件包目录 4.执行 redis-server.exe 使用netsta ...
- JAVA反射机制o
Reflection是Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性.例如,使用它能获得 Java 类中 ...
- 在TFS 2013中选择一周中的工作日,例如增加星期日
默认情况下,TFS在迭代视图中不计算周末的工作,如果出现调休的情况,则周末的工作日不会出现在迭代视图中,也不会参与燃尽图的计算.但是可以调整团队一周中的工作日,从而修正迭代计算方式,修改的方式参考下图 ...