Django学习笔记之——Forms
2023-09-14 08:58:20 时间
前面学习的都只是如何显示数据,但一直没有关于如何响应用户提交的数据。
表单,是在web中,用户与服务器交互的重要途径。
import django.forms
form django import forms
之间的区别是什么?
form在Django中扮演的角色有:
*显示form
*验证用户提交的数据
form的定义
~~~~~~~~~~
form的定义与model的定义非常相似:
____________________________________________
from django import forms
class BookForm(forms.Form):
isbn= forms.CharField(max_length=200)
title = forms.CharField(max_length=200)
--------------------------------------------
定义了一个BookForm表单,表单里有isbn与title两项。
BookForm可以生成html表单文本,如下:
____________________________
book_form = BookForm()
html = book_form.as_table()
print(html)
----------------------------
执行打印出的结果是:
tr th label for="id_isbn" Isbn: /label /th td input id="id_isbn" maxlength="50" name="isbn" type="text" / /td /tr
tr th label for="id_title" Title: /label /th td input id="id_title" maxlength="200" name="title" type="text" / /td /tr
可以看出,打印出来的文本没有包含 form 与 input type="submit" ,这些需要我们
在模板中指定。Form只负责isbn与title的输入,而不关心form的动作与提交方式。
所以,我们最好用模板的方法先定义好一个模板,如book-form.html:
_______________________________
form action="." method="get"
{{book_form}}
br
input type="submit"
/form
-------------------------------
在views.py中用render_to_response()生成HttpResponse:
____________________________________________________
def book_view(request):
book_form = BookForm()
response = render_to_response(book-form.html,
{book_form:book_form.as_table()})
----------------------------------------------------
返回的页面源码:
form action="." method="get"
tr th label for="id_isbn" Isbn: /label /th td input id="id_isbn" maxlength="50" name="isbn" type="text" / /td /tr
tr th label for="id_title" Title: /label /th td input id="id_title" maxlength="200" name="title" type="text" / /td /tr
br
input type="submit"
/form
Form除了as_table()方法,还有as_ul()与as_p()方法,默认是as_table()方法。
Form是在 django/forms/forms.py 定义的。
打开forms.py文件,可以了解到,Form继承于BaseForm。
BaseForm的定义大致如下:
___________________________________________________________________________
class BaseForm(object):
def __init__(self, data=None, files=None, auto_id=id_%s, prefix=None,
initial=None, label_suffix=None):
...
def as_table(self):
...
def as_ul(self):
...
def as_p(self):
...
def __str__(self):
return self.as_table()
class Form(BaseForm):
...
---------------------------------------------------------------------------
auto_id为 input id="id_xxx" ,控件的自动id格式。为或None表示不需要id。
label_suffix为lable名称的后缀,默认为":",可以改。比如:label_suffix="="
prefix为name的前缀,如果设置了prefix="aaa",那么 input name="aaa-xxx"
initial为初始值字典。
上面BookForm中只用到了一种域:CharField。除此之外还有很多种。
Fields定义在django/forms/fields.py文件里。
打开fields.py文件,可以看到除CharField外还有更多的Field供选择:
Field
|--CharField
| |--RegexField
| |--EmailField
| |--URLField
| |--IPAddressField
| |--GenericIPAddressField
| `--SlugField
|--IntegerField
| |--FloatField
| `--DecimalField
|--BaseTomporalField
| |--DateField
| |--TimeField
| `--DateTimeField
|--FileField #file选择文件
| `--ImageField
|--BooleanField #checkbox
| `--NullBooleanField #select:Unknow,Yes,No
|--ChoiceField #select
| |--TypedChoiceField
| |--FilePathField
| `--MultipleChoiceField
| `--TypedMultipleChoiceField
|--ComboField
`--MultiValueField
`--SplitDateTimeField
每种Field有个默认的Widget。
__________________________________
class Field(object):
widget = TextInput
...
class EmailField(CharField):
widget = EmailInput
...
class FileField(Field):
widget = ClearableFileInput
...
----------------------------------
Widget告诉Field生成哪种web控件。
我们也可以为Field指定Widget。
比如登陆表单:
_____________________________________________________________
class LoginForm(forms.Form):
#email = forms.EmailField()
email = forms.CharField(widget=widgets.EmailInput())
password = forms.CharField(widget=widgets.PasswordInput())
-------------------------------------------------------------
password这个域不能用明文显示,所以更改了widget。
所有的Widget都定义在django/forms/widgets.py中。
有如下控件:
Media, MediaDefiningClass, Widget, TextInput,
EmailInput, URLInput, NumberInput, PasswordInput,
HiddenInput, MultipleHiddenInput, ClearableFileInput,
FileInput, DateInput, DateTimeInput, TimeInput, Textarea,
CheckboxInput, SplitDateTimeWidget,
Select, NullBooleanSelect, SelectMultiple, RadioSelect,
CheckboxSelectMultiple, MultiWidget,
基于模型的表单
~~~~~~~~~~~~~~
根据模型的定义来自动定义表单。如下:
______________________________________
from django import forms
from models import Book
class BookModelForm(froms.ModelForm):
class Meta:
model = Book
--------------------------------------
而Book的定义在models.py里:
____________________________________________
class Book(models.Model):
isbn = models.CharField(max_length=50)
title = models.CharField(max_length=200)
author = models.ForeignKey(Author)
def __unicode__(self):
return self.title
--------------------------------------------
这样以来,BookModelForm也有了与Book对应的isbn,title,author。
保存ModelForm
~~~~~~~~~~~~~
ModelForm与一般的Form的重要区别是,ModelForm具有save()功能。能将表单里的数据
加入到数据库,并返回一个Model对象。
为了演示方便,我就不采用模板了。同样是引用上面BookModelForm与Book:
_________________________________________________________________
def add_book_view(request):
book_form = forms.BookModelForm(request.GET)
try:
book_model = book_form.save()
content = p Add + book_model.title + success! /p
except:
content = form action="." method="get"
content += book_form.as_p()
content += input type="submit" /form
return HttpResponse(content)
-----------------------------------------------------------------
并将add_book_view视图的url指定为r^add-book/。
第一次访问/add-book/时,由于GET中没有参数,所以在book_form.save()就会抛出异
常。在except中返回个表单给用户。用户填好后提交。这次再处理时,GET里就有数据
了,所以book_form.save()正常,最后输出success消息。
有时,我们在save()时仅仅是想验证一下用户的输入,并不打算提交到数据为。
这里,只要save(commit=False)即可。
如此,在save(commit=False)时返回了book模型的对象。我们可以继而对其进一步修改
,再保存到数据库。
_____________________________________________________
#book_model = book_form.save()
book_model = book_form.save(commit=False)
book_model.title = Balabala
book_model.save()
-----------------------------------------------------
第一行只是验证一下用户的输出是不是符合要求。然后对模型对象进行修改,最后才保
存到数据库去。就这样,在中间改了title,然后再保存到了数据库。
ModelForm显示个别域
~~~~~~~~~~~~~~~~~~~
ModelForm默认情况下,与Model是一致的。但是很多时候,并不是模型中所有的域都要
让用户填的。我们可以选择性地选择或排除个别域。
这里就要用到Meta的exclude或fields。exclude表示排除什么域,而fields表示需要显
示哪些域。二者不能同时使用。
_________________________________________________
class BookModelForm(forms.ModelForm):
class Meta:
model = Book
exclude = (author) #表示不显示author域
-------------------------------------------------
_________________________________________________
class BookModelForm(forms.ModelForm):
class Meta:
model = Book
fields = (title, isbn)
#表示只显示title与isbn域
-------------------------------------------------
重写ModelForm中的域
~~~~~~~~~~~~~~~~~~~
_________________________________________
class BookModelForm(forms.ModelForm):
isbn = forms.CharField(max_length=13)
class Meta:
model = Book
-----------------------------------------
将Book中指定的CharField(max_length=50),改成了13。
新增ModelForm中的域
~~~~~~~~~~~~~~~~~~~
______________________________________
class BookModelForm(forms.ModelForm):
review = forms.CharField()
class Meta:
model = Book
--------------------------------------
这样以来,BookModelForm不仅只有Book中的域,还有review。
表单的验证
~~~~~~~~~~
Form的is_valid()文件可以用来验证数据是否合法。
如果数据合法,Form对象则会有cleaned_data属性。如果不合法,则是errors。
__________________________________________________________________
def add_author_view(request):
content = None
if request.GET: # 检查GET是否有表单数据
author_form = forms.AuthorModelForm(request.GET)
if author_form.is_valid(): # 检查数据是否合法
print(author_form.cleaned_data)
try:
author_form.save()
content = p Success /p
except:
content = p Something wrong while saving. /p
else:
content = str(author_form.errors) # 用errors返回错误信息
else:
content = form action="."
content += forms.AuthorModelForm().as_p()
content += input type="submit" /form
return HttpResponse(content)
------------------------------------------------------------------
上面用到了author_form.is_valid()进行数据合法性验证。
如果成功,则会有author_form.cleaned_data,如果失败会有author_form.errors。
这两则只会存在一个,不会同时存在。
李名赫 博主从事的是物联网行业,目前在某知名智能家居科技公司担任家庭智能中心研发主管。欢迎交流!
表单,是在web中,用户与服务器交互的重要途径。
import django.forms
form django import forms
之间的区别是什么?
form在Django中扮演的角色有:
*显示form
*验证用户提交的数据
form的定义
~~~~~~~~~~
form的定义与model的定义非常相似:
____________________________________________
from django import forms
class BookForm(forms.Form):
isbn= forms.CharField(max_length=200)
title = forms.CharField(max_length=200)
--------------------------------------------
定义了一个BookForm表单,表单里有isbn与title两项。
BookForm可以生成html表单文本,如下:
____________________________
book_form = BookForm()
html = book_form.as_table()
print(html)
----------------------------
执行打印出的结果是:
tr th label for="id_isbn" Isbn: /label /th td input id="id_isbn" maxlength="50" name="isbn" type="text" / /td /tr
tr th label for="id_title" Title: /label /th td input id="id_title" maxlength="200" name="title" type="text" / /td /tr
可以看出,打印出来的文本没有包含 form 与 input type="submit" ,这些需要我们
在模板中指定。Form只负责isbn与title的输入,而不关心form的动作与提交方式。
所以,我们最好用模板的方法先定义好一个模板,如book-form.html:
_______________________________
form action="." method="get"
{{book_form}}
br
input type="submit"
/form
-------------------------------
在views.py中用render_to_response()生成HttpResponse:
____________________________________________________
def book_view(request):
book_form = BookForm()
response = render_to_response(book-form.html,
{book_form:book_form.as_table()})
----------------------------------------------------
返回的页面源码:
form action="." method="get"
tr th label for="id_isbn" Isbn: /label /th td input id="id_isbn" maxlength="50" name="isbn" type="text" / /td /tr
tr th label for="id_title" Title: /label /th td input id="id_title" maxlength="200" name="title" type="text" / /td /tr
br
input type="submit"
/form
Form除了as_table()方法,还有as_ul()与as_p()方法,默认是as_table()方法。
Form是在 django/forms/forms.py 定义的。
打开forms.py文件,可以了解到,Form继承于BaseForm。
BaseForm的定义大致如下:
___________________________________________________________________________
class BaseForm(object):
def __init__(self, data=None, files=None, auto_id=id_%s, prefix=None,
initial=None, label_suffix=None):
...
def as_table(self):
...
def as_ul(self):
...
def as_p(self):
...
def __str__(self):
return self.as_table()
class Form(BaseForm):
...
---------------------------------------------------------------------------
auto_id为 input id="id_xxx" ,控件的自动id格式。为或None表示不需要id。
label_suffix为lable名称的后缀,默认为":",可以改。比如:label_suffix="="
prefix为name的前缀,如果设置了prefix="aaa",那么 input name="aaa-xxx"
initial为初始值字典。
上面BookForm中只用到了一种域:CharField。除此之外还有很多种。
Fields定义在django/forms/fields.py文件里。
打开fields.py文件,可以看到除CharField外还有更多的Field供选择:
Field
|--CharField
| |--RegexField
| |--EmailField
| |--URLField
| |--IPAddressField
| |--GenericIPAddressField
| `--SlugField
|--IntegerField
| |--FloatField
| `--DecimalField
|--BaseTomporalField
| |--DateField
| |--TimeField
| `--DateTimeField
|--FileField #file选择文件
| `--ImageField
|--BooleanField #checkbox
| `--NullBooleanField #select:Unknow,Yes,No
|--ChoiceField #select
| |--TypedChoiceField
| |--FilePathField
| `--MultipleChoiceField
| `--TypedMultipleChoiceField
|--ComboField
`--MultiValueField
`--SplitDateTimeField
每种Field有个默认的Widget。
__________________________________
class Field(object):
widget = TextInput
...
class EmailField(CharField):
widget = EmailInput
...
class FileField(Field):
widget = ClearableFileInput
...
----------------------------------
Widget告诉Field生成哪种web控件。
我们也可以为Field指定Widget。
比如登陆表单:
_____________________________________________________________
class LoginForm(forms.Form):
#email = forms.EmailField()
email = forms.CharField(widget=widgets.EmailInput())
password = forms.CharField(widget=widgets.PasswordInput())
-------------------------------------------------------------
password这个域不能用明文显示,所以更改了widget。
所有的Widget都定义在django/forms/widgets.py中。
有如下控件:
Media, MediaDefiningClass, Widget, TextInput,
EmailInput, URLInput, NumberInput, PasswordInput,
HiddenInput, MultipleHiddenInput, ClearableFileInput,
FileInput, DateInput, DateTimeInput, TimeInput, Textarea,
CheckboxInput, SplitDateTimeWidget,
Select, NullBooleanSelect, SelectMultiple, RadioSelect,
CheckboxSelectMultiple, MultiWidget,
基于模型的表单
~~~~~~~~~~~~~~
根据模型的定义来自动定义表单。如下:
______________________________________
from django import forms
from models import Book
class BookModelForm(froms.ModelForm):
class Meta:
model = Book
--------------------------------------
而Book的定义在models.py里:
____________________________________________
class Book(models.Model):
isbn = models.CharField(max_length=50)
title = models.CharField(max_length=200)
author = models.ForeignKey(Author)
def __unicode__(self):
return self.title
--------------------------------------------
这样以来,BookModelForm也有了与Book对应的isbn,title,author。
保存ModelForm
~~~~~~~~~~~~~
ModelForm与一般的Form的重要区别是,ModelForm具有save()功能。能将表单里的数据
加入到数据库,并返回一个Model对象。
为了演示方便,我就不采用模板了。同样是引用上面BookModelForm与Book:
_________________________________________________________________
def add_book_view(request):
book_form = forms.BookModelForm(request.GET)
try:
book_model = book_form.save()
content = p Add + book_model.title + success! /p
except:
content = form action="." method="get"
content += book_form.as_p()
content += input type="submit" /form
return HttpResponse(content)
-----------------------------------------------------------------
并将add_book_view视图的url指定为r^add-book/。
第一次访问/add-book/时,由于GET中没有参数,所以在book_form.save()就会抛出异
常。在except中返回个表单给用户。用户填好后提交。这次再处理时,GET里就有数据
了,所以book_form.save()正常,最后输出success消息。
有时,我们在save()时仅仅是想验证一下用户的输入,并不打算提交到数据为。
这里,只要save(commit=False)即可。
如此,在save(commit=False)时返回了book模型的对象。我们可以继而对其进一步修改
,再保存到数据库。
_____________________________________________________
#book_model = book_form.save()
book_model = book_form.save(commit=False)
book_model.title = Balabala
book_model.save()
-----------------------------------------------------
第一行只是验证一下用户的输出是不是符合要求。然后对模型对象进行修改,最后才保
存到数据库去。就这样,在中间改了title,然后再保存到了数据库。
ModelForm显示个别域
~~~~~~~~~~~~~~~~~~~
ModelForm默认情况下,与Model是一致的。但是很多时候,并不是模型中所有的域都要
让用户填的。我们可以选择性地选择或排除个别域。
这里就要用到Meta的exclude或fields。exclude表示排除什么域,而fields表示需要显
示哪些域。二者不能同时使用。
_________________________________________________
class BookModelForm(forms.ModelForm):
class Meta:
model = Book
exclude = (author) #表示不显示author域
-------------------------------------------------
_________________________________________________
class BookModelForm(forms.ModelForm):
class Meta:
model = Book
fields = (title, isbn)
#表示只显示title与isbn域
-------------------------------------------------
重写ModelForm中的域
~~~~~~~~~~~~~~~~~~~
_________________________________________
class BookModelForm(forms.ModelForm):
isbn = forms.CharField(max_length=13)
class Meta:
model = Book
-----------------------------------------
将Book中指定的CharField(max_length=50),改成了13。
新增ModelForm中的域
~~~~~~~~~~~~~~~~~~~
______________________________________
class BookModelForm(forms.ModelForm):
review = forms.CharField()
class Meta:
model = Book
--------------------------------------
这样以来,BookModelForm不仅只有Book中的域,还有review。
表单的验证
~~~~~~~~~~
Form的is_valid()文件可以用来验证数据是否合法。
如果数据合法,Form对象则会有cleaned_data属性。如果不合法,则是errors。
__________________________________________________________________
def add_author_view(request):
content = None
if request.GET: # 检查GET是否有表单数据
author_form = forms.AuthorModelForm(request.GET)
if author_form.is_valid(): # 检查数据是否合法
print(author_form.cleaned_data)
try:
author_form.save()
content = p Success /p
except:
content = p Something wrong while saving. /p
else:
content = str(author_form.errors) # 用errors返回错误信息
else:
content = form action="."
content += forms.AuthorModelForm().as_p()
content += input type="submit" /form
return HttpResponse(content)
------------------------------------------------------------------
上面用到了author_form.is_valid()进行数据合法性验证。
如果成功,则会有author_form.cleaned_data,如果失败会有author_form.errors。
这两则只会存在一个,不会同时存在。
李名赫 博主从事的是物联网行业,目前在某知名智能家居科技公司担任家庭智能中心研发主管。欢迎交流!
相关文章
- Django组件:django-simple-captcha 使用
- django-序列化参数为空报错问题
- django笔记整理
- django命令(笔记,自己看的)
- Django学习笔记之——Start
- Django学习笔记之——Views
- 第三百一十二节,Django框架,Cookie
- django 简易博客开发 5 markdown支持、代码高亮、gravatar头像服务
- VS2013中Python学习笔记[Django Web的第一个网页]
- django模板语言的注释
- Django中如何使用django-celery完成异步任务2(转)
- django源码笔记-【1】(转)
- django模板中使用JQ代码实现瀑布流显示效果
- django缓存机制
- 转一篇:文档笔记之Django QuerySet
- 笔记6:Django基础
- 笔记5:Django知识一
- Django管理工具django-admin.py创建项目
- 【网址收藏】达内Django视频笔记收藏
- Python Django 多对多表设计
- Python Django 一对多之插入多条数据示例
- Python Django 一对一多表查询关联表字段
- Python Django 设置/更改响应头信息
- Django 模型系统(model)&ORM--进阶
- Django学习15 -- 验证码
- Django===django工作流
- 在Django实战中实用的数据格式转换【csv转json和json转csv】