神勇威武的苦咖啡 · django,存储整型数组 - CSDN文库· 2 周前 · |
气势凌人的电池 · django ...· 2 周前 · |
发财的黄花菜 · Django ForeignKey ...· 1 周前 · |
文雅的煎饼果子 · Django 多表查询 - ...· 1 周前 · |
坚强的遥控器 · Django之ForeignKey和Many ...· 1 周前 · |
乐观的滑板 · 国关学院2019年本科生双学位招生拟录名单· 4 周前 · |
慷慨的小刀 · 易烊千玺胡先煦罗一舟考编成功!三人被国家话剧 ...· 2 月前 · |
没读研的日记本 · 吴赟:10月底上汽大众大众品牌销量超111万 ...· 1 年前 · |
发财的李子 · 蔚来发布了这样的首款概念车EVE - 知乎· 1 年前 · |
乐观的机器猫 · 2023款东风风行S60 ...· 1 年前 · |
1、HTML中的表单:用来提交数据给服务器的,不管后台的服务器用的是Django还是PHP语言还是其他语言
2、Django中的表单:
1、渲染表单模板
2、表单验证数据是否合法, 回显功能(验证错误,输入数据不会被清空)
3、 可保留用户上次提交的数据
4、 数据类型转换(转换成相应的python类型)
说明:
一,表单form
为了接收用户的投票选择,我们需要在前段页面显示一个投票界面,让我们重写之前的polls/detail.html文件,代码如下:
{{ question.question_text }}
{% if error_message %}
{{ error_message }}
{% endif %}
{% csrf_token %}
{% for choice in question.choice_set.all %}
{{ choice.choice_text }}
{% endfor %}
简要说明:
forloop.counter:
值是一个整数,表示循环的次数。这个属性的值从 1 开始,因此第一次循环时,forloop.counter 等于 1
forloop.counter0:
forloop.counter0
与
forloop.counter
类似,不过是从零开始的。第一次循环时,其值为 0 。
forloop.revcounter:
值是一个整数,表示循环中剩余的元素数量。第一次循环时,
forloop.revcounter
的值是序列中要遍历的元素总数。最后一次循环时,
forloop.revcounter
的值为 1 。
forloop.revcounter0:
与
forloop.revcounter
类似,不过索引是基于零的。第一次循环时,
forloop.revcounter0
的值是序列中元素数量减去一。最后一次循环时,
forloop.revcounter0
的值为 0 。
forloop.first:
forloop.first
是个布尔值,第一次循环时为 True 。需要特殊处理第一个元素时很方便:
{% for object in objects %} {% if forloop.first %}
{% else %}
{% endif %} {{ object }}
{% endfor %}
forloop.last:
是个布尔值,最后一次循环时为
True
。经常用它在一组链接之间放置管道符号:
{% for link in links %}
{{ link }}{% if not forloop.last %} | {% endif %}
{% endfor %}
现在,让我们创建一个处理提交过来的数据视图,前面我们已经写了一个“占坑”的vote视图的url(polls/urls.py)
1 |
|
以及占坑的vote视图函数(polls.views.py),我们把坑填起来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
有些新的东西,我们要解释一下:
当有人对某个问题投票后,vote()视图重定向到了问卷的结果显示页面,下面我们来写这个处理结果页面的视图(polls/views.py):
1 2 3 4 5 |
|
同样,还需要些个模板polls/templates/polls/results.html (路由,视图,模板,模型都是这个套路)
1 2 3 4 5 6 7 |
{{ question.question_text }}
|
现在你可以到浏览器中访问/polls/1/ 了 ,投票了。你会看到一个结果页面,每投一次,它的内容就会更新一次。如果你提交的时候没有选择项目,则会得到一个错误提示。
如果你在前面漏掉了一部分操作没做,比如没有创建choice选项对象,那么可以按下面的操作,补充一下:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
为了方便,我将当前状态的各主要内容一并贴出,依次可以对照参考!
1 ——完整的mysite/urls.py文件如下:
1 2 3 4 5 6 7 |
|
2 ——完整的mysite/settings.py文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
|
3 ——完整的polls/views.py 应该如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
4 ——完整的polls/urls.py 应该如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
5 ——完整的polls.model.py文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
6 ——完整的polls/admin.py 文件如下:
1 2 3 4 5 6 7 |
|
7 ——完整的templates/polls/index.html 文件如下:
1 2 3 4 5 6 7 8 9 |
|
8 ——完整的templates/polls/detail.html 文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
{{ question.question_text }}
|
9 ——完整的templates/polls/results.html 文件如下:
1 2 3 4 5 6 7 |
{{ question.question_text }}
|
vote()视图没有对应的HTML 模板,它直接跳转到results视图去了。
运行服务器,测试各功能如下:
这是问卷列表页面:
这是“What's up” 问卷选项页面:
这是选择结果的页面:
这是没有选择选项时,提示错误信息的页面:
表单,在前端页面中属于最常见的一个东西了。基本上网站信息的提交都用到了表单,所以下面来学习Django中优雅的表单系统:Form
表单的主要作用是在网页上提供一个图形用户页面,用作采集和提供用户输入数据。
表单的基本结构:
get:使用URL传参:http://服务器地址?name1 = value&name2=value2(?表示传递参数,?后面采用name=value的形式传递,多个参数之间,用&链接)URL传参不安全,所有信息可在地址栏看到,并且可以通过地址栏随机传递其他数据。URL传递数据量有限,只能传递少量数据。
post:使用HTTP请求传递数据。URL地址栏不可见,比较安全。且传递数据量没有限制。
表单提交中中get和post方式的区别
input标签是输入框,是表单中最重要的部分。
<form action=
"外部链接路径"
.method=
"get/post"
.name=
"#"
>
<input type=
"text"
>输入文本框
<input type=
"password"
>输入密码框
<input type=
"button"
>输入按钮
<input type=
"reset"
>重置
<input type=
"submit"
>提交
<input type=
"file"
>文件
<input type=
"checkbox"
>多选框
<input type=
"checkbox"
checked
>代表多选框默认选择项
<input type=
"radio"
>单选框,注意name需一样
<input type=
"date"
>时间
<input type=
"checkbox"
>多选框
name:是指名字,因为提交的是键值对,所以必须要指定名字,否则无法提交,即使提交了也没有意义。
value:文本框的内容,一般用在不能输入的类型中,如改变按钮的名字等。
placeholder:占位内容,通常用于显示
readonly:只读模式,设置后无法修改输入框的内容
disabled:禁用状态
size:由于输入框是单行的,所以只能设置宽度
maxlength:限制输入框最大输入的字符个数
开发中表单提交是很常见的,表单的提交方式也有很多种。
1,使用submit按钮提交表单
<input type=
"submit"
value=
"提交"
>
2,使用button按钮提交表单
<input type=
"button"
value=
"提交"
>
3,使用js进行表单提交,将form表单进行标记,将form表单中的某个元素设置成点击事件,点击时候调用js函数,再用JS。
$(
"#id"
).submit()
label元素不会向用户呈现任何特殊效果。不过,它为鼠标用户改进了可用性。如果您在label元素内点击文本,就会触发此控件。也就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。
带有两个输入字段和相关标记的简单HTML表单:
Title
用户名: 密码: 密码确认: 爱好: basketball football skating
性别: boy girl
邮箱:
住址:
表单提交数据就是由HTML表单向后台传递信息,后台通过request.GET() 或者request.POST()获取。
12345678910111213141516171819202122 |
|
widget是form表单最重要的参数之一,指定渲染Widget时使用的widget类,举个例子:就是说这个form字段在HTML页面中为文本输入框,密码输入框,单选框,多选框。。。。。
12345 |
|
单radio值为字符串
123456 |
|
123456 |
|
123456 |
|
1 |
|
值为列表
12345678 |
|
在使用选择标签的时候,需要注意choices的选项可以从数据库获取,但是由于是静态子弹,获取的值无法更新,那么需要自定义构造方法从而达到目的。
1 |
|
上传文件字段(不能设置为主键)。默认情况下,该字段在HTML中表现为一个ClearableFileInput 标签。在数据库内,我们实际保存的是一个字符串类型,默认最大长度为100,可以通过max_length 参数自定义。真实的文件是保存在服务器的文件系统内的。
重要参数upload_to 用于设置上传地址的目录和文件名。如下例所示:
123456 |
|
Django很人性化的帮我们实现了根据日期生成目录的方式!
upload_to 参数也可以接收一个回调函数,该函数返回具体的路径字符串,如下例:
123456 |
|
例子中,user_directory_path 这种回调函数,必须接收两个参数,然后返回一个Unix风格的路径字符串。参数instace代表一个定义了FileField的模型的实例,说白了就是当前数据记录。filename是原本的文件名。
1 |
|
用于保存图像文件袋额字段。其基本用法和特征与FileField一样,只不过多了两个属性height和width。默认清洗下,该字段在HTML中表现为一个ClearableFileInput 标签。在数据库内,我们实际保存的是一个字符串类型。默认最大长度100,可以通过max_length 参数自定义。真实的图片是保存在服务器的文件系统内的。
使用Django的ImageField需要提前安装pillow模块 。
使用FileField或者ImageField字段的步骤:
安全建议
无论你如何保存上传的文件,一定要注意他们的内容和格式,避免安全漏洞!务必对所有上传文件进行安全检查,确保他们不出问题! 如果你不加任何检查就盲目的让任何人上传到你的服务器文档根目录内,比如上传了一个CGI 或者PHP脚本,很可能就会被访问的用户执行,这具有致命的危害。
1 |
|
一种用来保存文件路径信息的子段。在数据表内以字符串的形式存在,默认最大长度100,可以通过max_length参数设置。
他们包含有下面的一些参数:
比如:
1 |
|
他只匹配/home/images/foo.png ,但是不匹配 /home/images/foo/bar.png ,因为默认情况,只匹配文件名,而不管路径怎么样的。
数据库无法为自己生成uuid,因此需要如下使用default参数:
123456 |
|
views.py
1234567891011121314151617181920 |
|
urls.py
1234567891011 |
|
models.py
12345678 |
|
upload.html
12345678910111213141516171819 |
|
报错内容:
解决方法:
查看自己的HTML文件中,表单的action属性值结尾是否添加了“/”,我就是因为没有添加,找了半天错误,真尴尬。粗心大意
我们可以在APP目录下新建立一个myforms.py文件,然后再建立form。为什么要新建一个myforms.py呢?其好处显而易见:
一般情况下,使用一种东西就会受制于一种东西,但是这并不是Django的意愿。并非你接受了django表单的方便就需要接受这么丑陋的页面。Django表单时可以随你心愿定制的。
我们不但可以对标签名进行定制化,还可以限制输入的位数,比如下面代码,我们限制了输入九位,第十位就无法输入,而且并非所有的信息都是强制填的,可以根据需要来抉择,同样看下面代码,即使email空着不填,表单也能正常提交。
12345 |
|
每个表单字段都有一个对应的Widget class,它对应一个HTML表单Widget,我们可以使用Forms中的widget来对我们的前端表按照我们的要求进行改造
比如当我们需要做一个长文本输入框时候:
123456 |
|
html代码如下:
+ View Code
效果如下:
当我们想做一个下拉框的时候:
其views.py代码如下:
+ View Code
HTML代码如下:
+ View Code
结果展示如下:
对ChoiceField字段,Form默认的是集成select的widget,即使用HTML的列表形式
views.py 的代码如下(这里只修改了comment的代码):
1 |
|
我们为其设置了attrs,也就是HTML中的css属性。(要是想为整个表单或者更深度的定制一些css以及JavaScript,可以前往Django官方文档了解)
效果如下:
虽然字段类主要使用在表单类中,但是我们也可以直接实例化他们来使用,以便更好地了解他们是如何工作的。每个字段实例都有一个clean()方法,它接受一个参数,然后返回“清洁的”数据或者抛出一个django.forms.
12345678 |
|
每个字段类的构造函数至少接受这些参数。有些字段类接受额外的,字段特有的参数,但以下参数应该总能接受:
默认情况下,每个字段都假设必须有值,所以如果你传递一个空的值——不管是None,还是空字符串(" ")——clean() 都将引发一个ValidationError异常。
1234567891011121314151617 |
|
正如前面“输出表单为HTML”中解释的,字段默认label是通过将字段名中所有的下划线转换成空格并大写第一个字母生成的。如果默认的标签不合适,可以指定label。
12345678910 |
|
Your name: |
<input type=
|
Your Web site: |
<input type=
|
Comment: |
<input type=
|
label_suffix参数让你基于每个字段覆盖表单的label_suffix
123456789 |
|
initial 参数让你指定渲染未绑定的表单中的字段时使用的初始值。
widget参数让你指定渲染表单时使用的Widget类,更多信息参见上面。
error_messages 参数让你覆盖字段引发的异常中的默认信息。传递的是一个字典,其键为你想覆盖的错误信息。
validators 参数让你可以为字段提供一个验证函数的列表。
localize 参数启用表单数据的本地化,包括输入和输出。
has_changed() 方法用于决定字段的值是否从初始值发送了变化。返回True或者False。
django表单验证中比较有用的就是clean和cleaned_data了。
clean是在is_valid()内部调用的,cleaned_data主要用来检查字段是否符合定义的格式,读取表单返回的值,如果是则返回类型为字段dict型。
比如email = cleaned_data['email'] 读取name为“email”的表单提交值,并赋予email变量。
cleaned_data中的值类型与字段定义的Field类型一致。如果字段定义charfield,那么clean方法返回的cleaned_data中对应的字段值就是字符型,定义为ModelChoiceField,那么cleaned_data中字段值是某个model实例。定义为ModelMultipleChoiceField,则cleaned_data中字段值是model实例list。
首先我们看一下下面的案例:
1234567891011121314151617181920212223 |
|
针对于上面的问题,如何解决呢?——那就是Form表单
通常提交表单数据就是由HTML表单向后台传递信息,后台通过request.GET() 或者 request.POST()获取。
建一个Blog项目,并在template下新建两个html页面,一个注册页面命名为register,一个欢迎页面为welcome。
123456789101112131415 |
|
项目目录如下:
给template下两个html页面register和welcome填充内容。
register.html
12345678910111213141516171819 |
|
welcome.html
123456789101112 |
welcome to
|
在user1/models.py中创建表结构,代码如下:
1234567 |
|
ChariField 字符串字段,用于较短的字符串,需要max_length来指定VARCHAR数据库字段的大小。
同时,修改Bolg/settings.py的内容:
123456789101112131415161718192021222324 |
|
如果这里不熟悉请参考: Django连接MySQL数据库
并且,映射数据库,这一步不能忘记:
123456789 |
|
我们重构views.py中的代码
123456789101112131415 |
|
get() 中的username和password是取的register 里的username的值。以获取(request)注册的信息,保存为save()。
然后运行项目,并注册信息,代码如下:
12345678 |
|
然后我们注册信息,并提交。我们可以看到上面的register.html中用户名是唯一的,所以当我们注册相同的名称时候回报错500,并且传输失败。
下面在数据库看一下我们的注册信息
其中,3,5不显示,因为我输入了相同的用户名。如果输入不重复,则显示下面界面。
在上面的基础上,我们再实现一个表单流程,继续了解form表单的知识。
12345678910111213141516171819 |
|
123456789101112131415161718 |
|
然后,去配置urls一些基本的配置(比如模板,路由等)。
我们直接点开login.html 内容如下:
我们打开Django项目,从127.0.0.1:8000/user6/login/ 进入,如下:
直接访问地址就显示出这样一个简单的界面,由HTML文件可以看到并没有js代码对数据有效性进行验证,我们随机输入账号,密码,邮箱,则提交,显示登陆成功。如下:
从上面的代码我们发现,前端一个 {{ form }} 就能做出一个完整强大的表单。但是我们只能用account password 做名称吗?
不是的,这里我们可以定制其名字,并且可以限制输入位数等等各种操作。
在form里有一个参数:error_messages 在他这里就可以定义报错内容
1234567 |
|
12345678910 |
|
12345678910111213 |
|
同样的HTML代码也要新增:
12345678 |
|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
|
当我们输入不合法的时候,或者不是email格式的时候,会出现如下错误:
这样后端我们就有一套验证的机制了,就是通过is_valid()来判断用户输入是否合法!如果不合法就把返回的信息发送出去,如果合法获取数据,继续操作即可!
12345678910111213141516171819 |
|
HTML内更改如下:
123456789 |
|
这个后端验证是必须要有验证机制的,前端可以不写但是后端必须写,前端的JS是可以被禁用掉的,在实际的生产环境中比如登录和验证的时候,我们一般都使用 JQuery+AJAX 来判断用户的输入是否为空,假如JS被禁用(浏览器端可以设置禁用JS效果)的话,我们这个认证屏障是不是就消失了呢?(虽然一般不会禁用但是还是存在风险),所以我们一般做两种认证,在前端做一遍认证,在后端做一遍认证。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
|
为机甲的计时API写了如下例程,想对比一下PC上的Python性能(注:作为性能测试非常粗糙,因为主要是想作最简单的演示之用):def 开始(): 工具.计时器(常量.开始) 总耗时 = 0 次数 = 0 while 次数 < 10: 算三角函数() 工具.计时器(常量.暂停) 总耗时 = 工具.累计计时()
神勇威武的苦咖啡 · django,存储整型数组 - CSDN文库 2 周前 |
乐观的滑板 · 国关学院2019年本科生双学位招生拟录名单 4 周前 |
发财的李子 · 蔚来发布了这样的首款概念车EVE - 知乎 1 年前 |