如何使用95django_form进行表单处理?
- 内容介绍
- 文章标签
- 相关推荐
本文共计2588个文字,预计阅读时间需要11分钟。
目录+ form 1 + HTML 中 GET 和 POST: + 例 1,form 处理: + 例 2,django form: + 例 3,自动生成表单: + 例 4,手动渲染“
目录
form 1
HTML中GET和POST: 1
例1,form处理: 2
django form: 4
例2,自动生成表单: 6
例3,手动渲染字段: 11
form field: 11
form field args: 12
form
HTML中GET和POST:
处理表单时候只会用到POST 和 GET 方法。
Django 的登录表单使用POST 方法,在这个方法中浏览器组合表单数据、对它们进行编码以用于传输、将它们发送到服务器然后接收它的响应。
相反,GET 组合提交的数据为一个字符串,然后使用它来生成一个URL。 这个URL 将包含数据发送的地址以及数据的键和值。 如果你在Django 文档中做一次搜索,你会立即看到这点,此时将生成一个docs.djangoproject.com/search/?q=forms&release=1 形式的URL。
POST 和GET 用于不同的目的。
用于改变系统状态的请求 —— 例如,给数据库带来变化的请求 —— 应该使用POST。 GET 只应该用于不会影响系统状态的请求。
GET 还不适合密码表单,因为密码将出现在URL 中,以及浏览器的历史和服务器的日志中,而且都是以普通的文本格式。 它还不适合数据量大的表单和二进制数据,例如一张图片。 使用GET 请求作为管理站点的表单具有安全隐患:攻击者很容易模拟表单请求来取得系统的敏感数据。 POST,如果与其它的保护措施结合将对访问提供更多的控制,例如Django 的CSRF protection。
另一个方面,GET 适合网页搜索这样的表单,因为这种表示一个GET 请求的URL 可以很容易地作为书签、分享和重新提交。
例1,form处理:
mysite/polls/templates/polls/detail.html
<h1>{{ question.question_text }}</h1>
{% if error_message %}
<P><strong>{{ error_message }}</strong></P>
{% endif %}
<form action="{% url 'polls:vote' question.id %}">
{% 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>
mysite/polls/views.py
from django.shortcuts import render, get_object_or_404, reverse
from django.yiyibooks.cn/xx/Django_1.11.6/topics/forms/index.html#html-forms
若表单使用相同的html,可循环迭代每个字段来减少重复代码;
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
{{ field }}属性:
{{ field.label }},字段的label,如Email;
{{ field.label_tag }},包含在HTML label标签中的字段label,它包含表单的label_suffix,如默认label_suffix是冒号;
{{ field.id_for_label }},手动渲染字段用到,如<label for="id_email">Email:</label>,lable的for对应{{ field.id_for_label }};
{{ field.value }},字段的值,如someone@ane56.com;
{{ field.html_name }},输入元素的name属性中将使用的名称,它将考虑到表单的前缀;
{{ field.help_text }},与该字段关联的提示信息(帮助文档);
{{ field.errors }},输出一个<ul>,包含这个字段的验证错误信息;
表单验证:
view中在调用form.is_valid()时验证;
模板中{{ form.non_filed_errors }}、{{ field.errors }}访问errors属性时隐式调用;
field手动校验:
>>> form = forms.EmailField()
>>> form.clean('jowin@ane56.com')
'jowin@ane56.com'
>>> form.clean('test')
……
raise ValidationError(errors)
django.core.exceptions.ValidationError: ['Enter a valid email address.']
>>> from django import forms
>>> class NameForm(forms.Form):
... your_name = forms.CharField(label='your name', max_length=100)
...
>>> form = NameForm()
>>> form.is_bound
False
>>> form.as_p() #表单呈现选项,将其渲染在<p>标签中;label标签为input元素定义标注,label标签的for属性应与相关元素的id属性相同
'<p><label for="id_your_name">your name:</label> <input type="text" name="your_name" maxlength="100" required id="id_your_name" /></p>'
>>> form.as_table() #以表格形式将其渲染在<tr>中
'<tr><th><label for="id_your_name">your name:</label></th><td><input type="text" name="your_name" maxlength="100" required id="id_your_name" /></td></tr>'
>>> form.as_ul() #将其渲染在<li>标签中
'<li><label for="id_your_name">your name:</label> <input type="text" name="your_name" maxlength="100" required id="id_your_name" /></li>'
>>> form=NameForm({'your_name':'jowin'})
>>> form.is_bound #绑定表单和未绑定表单
True
>>> form
<NameForm bound=True, valid=Unknown, fields=(your_name)>
>>> form.cleaned_data['your_name'] #访问数据前没有form.is_valid()抛no attribute
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'NameForm' object has no attribute 'cleaned_data'
>>> form.is_valid() #做2件事,1为所有字段运行验证的程序,若所有字段都是合法数据返回True,2并将表单的数据放到cleaned_data属性中
True
>>> form.cleaned_data['your_name']访问数据前要先执行form.is_valid()
'jowin'
>>> form=NameForm({})
>>> form.is_bound
True
>>> form.is_valid()
False
>>> form.errors
{'your_name': ['This field is required.']}
>>> form = NameForm({'your_name':'jowin'*50})
>>> form.is_bound
True
>>> form.is_valid()
False
>>> form.errors
{'your_name': ['Ensure this value has at most 100 characters (it has 250).']}
例2,自动生成表单:
出版社、作者、书籍案例;
模板中用{{ form }}自动生成;
<form method="post" action="">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
(webproject) C:\webproject\mysite>django-admin startapp books
(webproject) C:\webproject\mysite>pip install django-bootstrap3
github.com/dyve/django-bootstrap3
mysite/mysite/settings.py
INSTALLED_APPS = [
'bootstrap3',
mysite/books/models.py
from django.db import models
from django import forms
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __str__(self):
return self.name
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
def __str__(self):
return '{} {}'.format(self.first_name, self.last_name)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
def __str__(self):
return self.title
mysite/books/forms.py
from django import forms
class PublisherForm(forms.Form):
name = forms.CharField(label='Your name', max_length=30)
address = forms.CharField(max_length=50)
city = forms.CharField(max_length=60)
state_province = forms.CharField(max_length=30)
country = forms.CharField(max_length=20)
website = forms.CharField(max_length=50)
mysite/books/views.py
from django.shortcuts import render, redirect
from .models import Publisher
from .forms import PublisherForm
from django.cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" >
<script src="cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<div class="container">
<form method="post" class="form">
{% csrf_token %}
添加</h1>
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">
{% bootstrap_icon "star" %} Submit
</button>
{% endbuttons %}
</form>
</div>
</html>
(webproject) C:\webproject\mysite>python manage.py makemigrations
(webproject) C:\webproject\mysite>python manage.py migrate
mysite/books/urls.py
from django.conf.urls import url
from . import views
app_name = 'books'
urlpatterns = [
url(r'^$', views.publisher_add, name='index'),
]
mysite/mysite/urls.py
urlpatterns = [
url(r'^books/', include('books.urls')),
url(r'^admin/', admin.site.urls),
]
(webproject) C:\webproject\mysite>python manage.py runserver
例3,手动渲染字段:
自己对展示的表单字段进行先后排序;
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea)
sender = forms.EmailField()
cc_myself = forms.BooleanField(required=False)
{{ form.non_field_errors }} #
<div class="fieldWrapper">
{{ form.subject.errors }}
<label for="{{ form.subject.id_for_label }}">Email subject:</label>
{{ form.subject }}
</div>
<div class="fieldWrapper">
{{ form.message.errors }}
<label for="{{ form.message.id_for_label }}">Your message:</label>
{{ form.message }}
</div>
<div class="fieldWrapper">
{{ form.sender.errors }}
<label for="{{ form.sender.id_for_label }}">Your email address:</label>
{{ form.sender }}
</div>
<div class="fieldWrapper">
{{ form.cc_myself.errors }}
<label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label>
{{ form.cc_myself }}
</div>
form field:
docs.djangoproject.com/en/2.1/ref/forms/fields/
BooleanField
CharField
ChoiceField
DateField
DateTimeField
DecimalField
EmailField #实际是CharField的子类,只不过是在其基础上加了些验证
FileField
FilePathField
FloatField #py float
ImageField
IntergerField #py int
form field args:
required
label
label_suffix
widget
help_text
error_messages
本文共计2588个文字,预计阅读时间需要11分钟。
目录+ form 1 + HTML 中 GET 和 POST: + 例 1,form 处理: + 例 2,django form: + 例 3,自动生成表单: + 例 4,手动渲染“
目录
form 1
HTML中GET和POST: 1
例1,form处理: 2
django form: 4
例2,自动生成表单: 6
例3,手动渲染字段: 11
form field: 11
form field args: 12
form
HTML中GET和POST:
处理表单时候只会用到POST 和 GET 方法。
Django 的登录表单使用POST 方法,在这个方法中浏览器组合表单数据、对它们进行编码以用于传输、将它们发送到服务器然后接收它的响应。
相反,GET 组合提交的数据为一个字符串,然后使用它来生成一个URL。 这个URL 将包含数据发送的地址以及数据的键和值。 如果你在Django 文档中做一次搜索,你会立即看到这点,此时将生成一个docs.djangoproject.com/search/?q=forms&release=1 形式的URL。
POST 和GET 用于不同的目的。
用于改变系统状态的请求 —— 例如,给数据库带来变化的请求 —— 应该使用POST。 GET 只应该用于不会影响系统状态的请求。
GET 还不适合密码表单,因为密码将出现在URL 中,以及浏览器的历史和服务器的日志中,而且都是以普通的文本格式。 它还不适合数据量大的表单和二进制数据,例如一张图片。 使用GET 请求作为管理站点的表单具有安全隐患:攻击者很容易模拟表单请求来取得系统的敏感数据。 POST,如果与其它的保护措施结合将对访问提供更多的控制,例如Django 的CSRF protection。
另一个方面,GET 适合网页搜索这样的表单,因为这种表示一个GET 请求的URL 可以很容易地作为书签、分享和重新提交。
例1,form处理:
mysite/polls/templates/polls/detail.html
<h1>{{ question.question_text }}</h1>
{% if error_message %}
<P><strong>{{ error_message }}</strong></P>
{% endif %}
<form action="{% url 'polls:vote' question.id %}">
{% 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>
mysite/polls/views.py
from django.shortcuts import render, get_object_or_404, reverse
from django.yiyibooks.cn/xx/Django_1.11.6/topics/forms/index.html#html-forms
若表单使用相同的html,可循环迭代每个字段来减少重复代码;
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
{{ field }}属性:
{{ field.label }},字段的label,如Email;
{{ field.label_tag }},包含在HTML label标签中的字段label,它包含表单的label_suffix,如默认label_suffix是冒号;
{{ field.id_for_label }},手动渲染字段用到,如<label for="id_email">Email:</label>,lable的for对应{{ field.id_for_label }};
{{ field.value }},字段的值,如someone@ane56.com;
{{ field.html_name }},输入元素的name属性中将使用的名称,它将考虑到表单的前缀;
{{ field.help_text }},与该字段关联的提示信息(帮助文档);
{{ field.errors }},输出一个<ul>,包含这个字段的验证错误信息;
表单验证:
view中在调用form.is_valid()时验证;
模板中{{ form.non_filed_errors }}、{{ field.errors }}访问errors属性时隐式调用;
field手动校验:
>>> form = forms.EmailField()
>>> form.clean('jowin@ane56.com')
'jowin@ane56.com'
>>> form.clean('test')
……
raise ValidationError(errors)
django.core.exceptions.ValidationError: ['Enter a valid email address.']
>>> from django import forms
>>> class NameForm(forms.Form):
... your_name = forms.CharField(label='your name', max_length=100)
...
>>> form = NameForm()
>>> form.is_bound
False
>>> form.as_p() #表单呈现选项,将其渲染在<p>标签中;label标签为input元素定义标注,label标签的for属性应与相关元素的id属性相同
'<p><label for="id_your_name">your name:</label> <input type="text" name="your_name" maxlength="100" required id="id_your_name" /></p>'
>>> form.as_table() #以表格形式将其渲染在<tr>中
'<tr><th><label for="id_your_name">your name:</label></th><td><input type="text" name="your_name" maxlength="100" required id="id_your_name" /></td></tr>'
>>> form.as_ul() #将其渲染在<li>标签中
'<li><label for="id_your_name">your name:</label> <input type="text" name="your_name" maxlength="100" required id="id_your_name" /></li>'
>>> form=NameForm({'your_name':'jowin'})
>>> form.is_bound #绑定表单和未绑定表单
True
>>> form
<NameForm bound=True, valid=Unknown, fields=(your_name)>
>>> form.cleaned_data['your_name'] #访问数据前没有form.is_valid()抛no attribute
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'NameForm' object has no attribute 'cleaned_data'
>>> form.is_valid() #做2件事,1为所有字段运行验证的程序,若所有字段都是合法数据返回True,2并将表单的数据放到cleaned_data属性中
True
>>> form.cleaned_data['your_name']访问数据前要先执行form.is_valid()
'jowin'
>>> form=NameForm({})
>>> form.is_bound
True
>>> form.is_valid()
False
>>> form.errors
{'your_name': ['This field is required.']}
>>> form = NameForm({'your_name':'jowin'*50})
>>> form.is_bound
True
>>> form.is_valid()
False
>>> form.errors
{'your_name': ['Ensure this value has at most 100 characters (it has 250).']}
例2,自动生成表单:
出版社、作者、书籍案例;
模板中用{{ form }}自动生成;
<form method="post" action="">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
(webproject) C:\webproject\mysite>django-admin startapp books
(webproject) C:\webproject\mysite>pip install django-bootstrap3
github.com/dyve/django-bootstrap3
mysite/mysite/settings.py
INSTALLED_APPS = [
'bootstrap3',
mysite/books/models.py
from django.db import models
from django import forms
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __str__(self):
return self.name
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
def __str__(self):
return '{} {}'.format(self.first_name, self.last_name)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
def __str__(self):
return self.title
mysite/books/forms.py
from django import forms
class PublisherForm(forms.Form):
name = forms.CharField(label='Your name', max_length=30)
address = forms.CharField(max_length=50)
city = forms.CharField(max_length=60)
state_province = forms.CharField(max_length=30)
country = forms.CharField(max_length=20)
website = forms.CharField(max_length=50)
mysite/books/views.py
from django.shortcuts import render, redirect
from .models import Publisher
from .forms import PublisherForm
from django.cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" >
<script src="cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<div class="container">
<form method="post" class="form">
{% csrf_token %}
添加</h1>
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">
{% bootstrap_icon "star" %} Submit
</button>
{% endbuttons %}
</form>
</div>
</html>
(webproject) C:\webproject\mysite>python manage.py makemigrations
(webproject) C:\webproject\mysite>python manage.py migrate
mysite/books/urls.py
from django.conf.urls import url
from . import views
app_name = 'books'
urlpatterns = [
url(r'^$', views.publisher_add, name='index'),
]
mysite/mysite/urls.py
urlpatterns = [
url(r'^books/', include('books.urls')),
url(r'^admin/', admin.site.urls),
]
(webproject) C:\webproject\mysite>python manage.py runserver
例3,手动渲染字段:
自己对展示的表单字段进行先后排序;
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea)
sender = forms.EmailField()
cc_myself = forms.BooleanField(required=False)
{{ form.non_field_errors }} #
<div class="fieldWrapper">
{{ form.subject.errors }}
<label for="{{ form.subject.id_for_label }}">Email subject:</label>
{{ form.subject }}
</div>
<div class="fieldWrapper">
{{ form.message.errors }}
<label for="{{ form.message.id_for_label }}">Your message:</label>
{{ form.message }}
</div>
<div class="fieldWrapper">
{{ form.sender.errors }}
<label for="{{ form.sender.id_for_label }}">Your email address:</label>
{{ form.sender }}
</div>
<div class="fieldWrapper">
{{ form.cc_myself.errors }}
<label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label>
{{ form.cc_myself }}
</div>
form field:
docs.djangoproject.com/en/2.1/ref/forms/fields/
BooleanField
CharField
ChoiceField
DateField
DateTimeField
DecimalField
EmailField #实际是CharField的子类,只不过是在其基础上加了些验证
FileField
FilePathField
FloatField #py float
ImageField
IntergerField #py int
form field args:
required
label
label_suffix
widget
help_text
error_messages

