当前位置:
首页 > Python基础教程 >
-
Form和ModelForm组件(2)
body>
<div class="container">
<div class="row">
<form action="/login2/" method="post" novalidate class="form-horizontal">
{% csrf_token %}
<div class="form-group">
<label for="{{ form_obj.username.id_for_label }}"
class="col-md-2 control-label">{{ form_obj.username.label }}</label>
<div class="col-md-10">
{{ form_obj.username }}
<span class="help-block">{{ form_obj.username.errors.0 }}</span>
</div>
</div>
<div class="form-group">
<label for="{{ form_obj.pwd.id_for_label }}" class="col-md-2 control-label">{{ form_obj.pwd.label }}</label>
<div class="col-md-10">
{{ form_obj.pwd }}
<span class="help-block">{{ form_obj.pwd.errors.0 }}</span>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{{ form_obj.gender.label }}</label>
<div class="col-md-10">
<div class="radio">
{% for radio in form_obj.gender %}
<label for="{{ radio.id_for_label }}">
{{ radio.tag }}{{ radio.choice_label }}
</label>
{% endfor %}
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default">注册</button>
</div>
</div>
</form>
</div>
</div>
<script src="/static/jquery-3.2.1.min.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
</body>
</html>
批量添加样式
可通过重写form类的init方法来实现。
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三",
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短8位"
}
...
def __init__(self, *args, **kwargs):
super(LoginForm, self).__init__(*args, **kwargs)
for field in iter(self.fields):
self.fields[field].widget.attrs.update({
'class': 'form-control'
})
简单写一个小项目:book表的添加和数据展示
views.py内容如下:
from django.shortcuts import render,HttpResponse,redirect
from app01 import models
from django import forms
# Create your views here.
class BookForm(forms.Form):
title = forms.CharField(
max_length=16,
label='书名:',
initial='zhang',
# widget = forms.widgets.PasswordInput(attrs={'class': 'form-control'},render_value=True),
widget = forms.widgets.TextInput(attrs={'class': 'form-control'},),
)
# title2 = forms.CharField(
# max_length=16,
# label='书名:',
# initial='zhang',
# # widget = forms.widgets.PasswordInput(attrs={'class': 'form-control'},render_value=True),
# widget=forms.widgets.TextInput(attrs={'class': 'form-control'}, ),
#
# )
sex = forms.ChoiceField(
choices=(
('1','男'),
('2','女'),
)
,
label='性别:',
# widget=forms.widgets.RadioSelect(),
# widget=forms.widgets.RadioSelect(),
# widget=forms.widgets.SelectMultiple(attrs={'class':'form-control'}),
widget=forms.widgets.Select(attrs={'class':'form-control'}),
# widget=forms.widgets.CheckboxInput(),
# widget=forms.widgets.CheckboxSelectMultiple(),
)
publishDate = forms.DateField(
label='出版日期:',
widget=forms.widgets.TextInput(attrs={'type':'date','class':'form-control'}),
)
price=forms.DecimalField(
max_digits=5,
decimal_places=2,
label='书籍的价格:',
widget=forms.widgets.NumberInput(attrs={'class': 'form-control'}
))
# publish = forms.ModelChoiceField(
# label='出版社:',
# queryset=models.Publish.objects.all(),
# widget=forms.widgets.Select(attrs={'class': 'form-control'}
# ))
publish_id = forms.ChoiceField(
label='出版社:',
widget=forms.widgets.Select(attrs={'class': 'form-control'}
))
authors = forms.ModelMultipleChoiceField(
queryset=models.Author.objects.all(),
widget = forms.widgets.SelectMultiple(attrs={'class': 'form-control'}
))
def __init__(self,*args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['publish_id'].choices = models.Publish.objects.values_list('pk','name')
def index(request):
if request.method == 'GET':
form_obj = BookForm()
return render(request,'index.html',{'form_obj':form_obj})
else:
print(request.POST)
form_obj = BookForm(request.POST)
print(form_obj.is_valid())
print(form_obj.errors)
if form_obj.is_valid():
print(form_obj.cleaned_data)
authors_obj = form_obj.cleaned_data.pop('authors')
new_book_obj = models.Book.objects.create(**form_obj.cleaned_data)
new_book_obj.authors.add(*authors_obj)
return redirect('show')
else:
print(form_obj.errors)
return render(request,'index.html',{'form_obj':form_obj})
def show(request):
book_objs = models.Book.objects.all()
return render(request,'show.html',{'book_objs':book_objs})
def edit_book(request,n):
return HttpResponse('欢迎来到编辑页面')
def delete_book(request,n):
return HttpResponse('欢迎来到删除页面')
urls.py内容如下
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index,name='index'),
url(r'^show/', views.show,name='show'),
url(r'^edit_book/(\d+)/', views.edit_book,name='edit_book'),
url(r'^delete_book/(\d+)/', views.delete_book,name='delete_book'),
]
index.html内容如下:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'bootstrap-3.3.0-dist/dist/css/bootstrap.min.css' %}">
</head>
<body>
<h1>展示页面</h1>
{#<div>#}
{# {{ form_obj.as_p }}#}
{##}
{#</div>#}
{#{% for field in form_obj %}#}
{# <div>#}
{# {{ field }}#}
{# </div>#}
{##}
{#{% endfor %}#}
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form action="" novalidate method="post">
{% for field in form_obj %}
<div class="form-group {% if field.errors.0 %}has-error{% endif %}">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
<span class="text-danger">{{ field.errors.0 }}</span>
</div>
{% endfor %}
{# <div class="form-group">#}
{# <label for="{{ form_obj.sex.id_for_label }}">{{ form_obj.sex.label }}</label>#}
{# {{ form_obj.sex }}#}
{# {{ form_obj.sex.errors.0 }}#}
{# </div>#}
{# <div class="form-group">#}
{# <label for="{{ form_obj.publishDate.id_for_label }}">{{ form_obj.publishDate.label }}</label>#}
{# {{ form_obj.publishDate }}#}
{# {{ form_obj.publishDate.errors.0 }}#}
{# </div>#}
{# <div class="form-group">#}
{# <label for="{{ form_obj.price.id_for_label }}">{{ form_obj.price.label }}</label>#}
{# {{ form_obj.price }}#}
{# <span class="text-danger">{{ form_obj.price.errors.0 }}</span>#}
{# </div>#}
{# <div class="form-group">#}
{# <label for="{{ form_obj.publish.id_for_label }}">{{ form_obj.publish.label }}</label>#}
{# {{ form_obj.publish }}#}
{# <span class="text-danger">{{ form_obj.publish.errors.0 }}</span>#}
{# </div>#}
{# <div class="form-group">#}
{# <label for="{{ form_obj.authors.id_for_label }}">{{ form_obj.authors.label }}</label>#}
{# {{ form_obj.authors }}#}
{# <span class="text-danger">{{ form_obj.authors.errors.0 }}</span>#}
{# </div>#}
<input type="submit">
</form>
</div>
</div>
</div>
<div>
</div>
</body>
<script src="{% static 'bootstrap-3.3.0-dist/dist/jQuery/jquery-3.1.1.js' %}"></script>
<script src="{% static 'bootstrap-3.3.0-dist/dist/js/bootstrap.min.js' %}"></script>
</html>
show.html内容如下
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'bootstrap-3.3.0-dist/dist/css/bootstrap.min.css' %}">
</head>
<body>
<h1>数据展示</h1>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<table class="table">
<thead>
<tr>
<th>id</th>
<th>title</th>
<th>性别</th>
<th>出版日期</th>
<th>出版社</th>
<th>作者</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for book_obj in book_objs %}
<tr>
<td>{{ book_obj.pk }}</td>
<td>{{ book_obj.title }}</td>
<td>{{ book_obj.get_sex_display }}</td>
<td>{{ book_obj.publishDate|date:'Y-d-m' }}</td>
<td>{{ book_obj.publish.name }}</td>
<td>
{% for author in book_obj.authors.all %}
{{ author.name }}
{% endfor %}
</td>
<td>
<a class="btn btn-warning" href="{% url 'edit_book' book_obj.pk %}">编辑</a>
<a class="btn btn-danger" href="{% url 'delete_book' book_obj.pk %}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
<script src="{% static 'bootstrap-3.3.0-dist/dist/jQuery/jquery-3.1.1.js' %}"></script>
<script src="{% static 'bootstrap-3.3.0-dist/dist/js/bootstrap.min.js' %}"></script>
</html>
别忘了在settings.py中配置静态文件
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'statics'),
]
别忘了去下载一个bootstrap和jquery然后在上面的html文件中引入一下。
models.py文件内容如下:
from django.db import models
# Create your models here.
from django.db import models
# Create your models here.
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
age=models.IntegerField()
authorDetail=models.OneToOneField(to="AuthorDetail",to_field="nid")
def __str__(self):
return self.name
class AuthorDetail(models.Model):
nid = models.AutoField(primary_key=True)
birthday=models.DateField()
telephone=models.BigIntegerField()
addr=models.CharField( max_length=64)
class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
city=models.CharField( max_length=32)
email=models.EmailField()
def __str__(self):
return self.name
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField( max_length=32)
sex_choice = (
(1,'男'),
(2,'女'),
)
sex = models.IntegerField(choices=sex_choice,default=1)
publishDate=models.DateField()
price=models.DecimalField(max_digits=5,decimal_places=2)
publish=models.ForeignKey(to="Publish",to_field="nid")
authors=models.ManyToManyField(to='Author',)
def __str__(self):
return self.title
别忘了给每个表添加一些数据。
七 ModelForm
通常在Django项目中,我们编写的大部分都是与Django 的模型紧密映射的表单。 举个例子,你也许会有个Book 模型,并且你还想创建一个form表单用来添加和编辑书籍信息到这个模型中。 在这种情况下,在form表单中定义字段将是冗余的,因为我们已经在模型中定义了那些字段。
基于这个原因,Django 提供一个辅助类来让我们可以从Django 的模型创建Form,这就是ModelForm。
modelForm定义
form与model的终极结合,会根据你model中的字段转换成对应的form字段,并且并你生成标签等操作。
比如你的models中的表是下面的内容:
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField( max_length=32)
publishDate=models.DateField()
price=models.DecimalField(max_digits=5,decimal_places=2)
publish=models.ForeignKey(to="Publish",to_field="nid")
authors=models.ManyToManyField(to='Author',)
def __str__(self):
return self.title
modelform类的写法。
class BookForm(forms.ModelForm):
class Meta:
model = models.Book
fields = "__all__"
labels = {
"title": "书名",
"price": "价格"
}
widgets = {
"password": forms.widgets.PasswordInput(attrs={"class": "c1"}),
"publishDate": forms.widgets.DateInput(attrs={"type": "date"}),
}
class Meta下常用参数:
model = models.Book # 对应的Model中的类
fields = "__all__" # 字段,如果是__all__,就是表示列出所有的字段
exclude = None # 排除的字段
labels = None # 提示信息
help_texts = None # 帮助提示信息
widgets = None # 自定义插件
error_messages = None # 自定义错误信息
error_messages = { 'title':{'required':'不能为空',...} #每个字段的所有的错误都可以写,...是省略的意思,复制黏贴我代码的时候别忘了删了...}
批量添加样式:和form的一样
class BookForm(forms.ModelForm): #password = forms.CharField(min_length=10) #可以重写字段,会覆盖modelform中的这个字段,那么modelform下面关于这个字段的设置就会被覆盖,比如果设置插件啊,error_messages啊等等,
r_password = forms.CharField() #想多验证一些字段可以单独拿出来写,按照form的写法,写在Meta的上面或者下面都可以
class Meta:
model = models.Book
# fields = ['title','price']
fields = "__all__" #['title,'price'] 指定字段生成form
# exclude=['title',] #排除字段
labels = {
"title": "书名",
"price"
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式