Python Django的分页,Form验证,中间件
本节内容
-
Django的分页
-
Form
-
中间件
1 Django 分页
1.1 Django自带的分页
1.首先来看下我的测试数据环境
############ models.py ############## class User(models.Model): username = models.CharField(max_length=32) password = models.CharField(max_length=32) class Host(models.Model): hostname = models.CharField(max_length=32) ip = models.GenericIPAddressField() user = models.ForeignKey('User') ############ views.py ############## from app import models # Create your views here. def create(request): models.User.objects.create(username='helei',password='123') models.User.objects.create(username='alex',password='123') models.User.objects.create(username='egon',password='123') for i in range(1,201): models.Host.objects.create(hostname='www.%s.com'%i,ip='192.168.1.%s'%i,user_id=1) return HttpResponse('添加成功') ############ urls.py ############## from app import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^create/$', views.create), ]
2.来配置一个index来显示数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css"> </head> <body> <div style="width: 800px;margin: 0 auto"> <table class="table table-hover"> <h1>主机列表</h1> <tr> <th>ID</th> <th>主机名</th> <th>IP</th> </tr> {% for obj in obj_list %} <tr> <td>{{ obj.id }}</td> <td>{{ obj.hostname }}</td> <td>{{ obj.ip }}</td> </tr> {% endfor %} </table> </div> </body> </html> ############### views.py ############## def index(request): obj_list = models.Host.objects.all() return render(request,'index.html',{'obj_list':obj_list})
3.页面内容正常显示,但是显示的是所有的数据信息,不好看。下面我们利用Django自带的分页功能来美化~?
在使用Django的分页是会用到Django的一个模块 paginator ,下面介绍下这个模块
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
EmptyPage, PageNotAnInteger为两个报错的信息,
这里主要介绍paginator
#### 参数说明 #### paginator = Paginator(L, 10) # per_page: 每页显示条目数量 # count: 数据总个数 # num_pages:总页数 # page_range:总页数的索引范围,如: (1,10),(1,200) # page: page对象 posts = paginator.page(current_page) # has_next 是否有下一页 # next_page_number 下一页页码 # has_previous 是否有上一页 # previous_page_number 上一页页码 # object_list 分页之后的数据列表 # number 当前页 # paginator paginator对象
终于写完了。 利用Django自带的分页函数最多就搞成这样了。 最多了。maybe
######## urls.py ######## from app import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^create/$', views.create), url(r'^index/$', views.index), url(r'^index/(?P<pid>\d+)$', views.index), ] ######## views.py ######## def index(request,pid=1): obj_list = models.Host.objects.all() # 所有的数据对象 page_obj = Paginator(obj_list,10) # 定义一个分页对象实例 pages = page_obj.page(pid) # 传递页数给page_obj对象 return render(request,'index.html',{'pages':pages}) # pages.object_list 分页后的数据 ######## index.html ######## <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css"> </head> <body> <div style="width: 800px;margin: 0 auto"> <table class="table table-hover"> <h1>主机列表</h1> <tr> <th>ID</th> <th>主机名</th> <th>IP</th> </tr> {% for obj in pages.object_list %} <tr> <td>{{ obj.id }}</td> <td>{{ obj.hostname }}</td> <td>{{ obj.ip }}</td> </tr> {% endfor %} </table> <nav aria-label="..."> <ul class="pagination"> {% if pages.has_previous %} <li><a href="/index/{{ pages.previous_page_number }}">上一页</a></li> {% endif %} {% for row in pages.paginator.page_range %} {% if row == pages.number %} <li class="active"><a href="{{ row }}">{{ row }}</a></li> {% else %} <li><a href="{{ row }}">{{ row }}</a></li> {% endif %} {% endfor %} {% if pages.has_next %} <li><a href="/index/{{ pages.next_page_number }}">下一页</a></li> {% endif %} </ul> </nav> </div> </body> </html>
2.1 自定义分页
上面的已经很好了,但是不是最屌的。 哈哈哈哈,不多说了,按照上边的思路,自己写一个分页函数来实现和上边基本类似的功能。go
写好了, 但是都写好了,分别说下各个函数中的代码功能吧。
1.urls.py
这里主要看最后的两个(自定义分页专用),
这里简单说明一下,匹配以/home/开头的url,都跳转到views.home进行处理,这里我给了home函数默认参数,让他可以处理这两个URL的数据。这一点可以在views.py中的home函数中看到。
from app import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^create/$', views.create), url(r'^index/$', views.index), url(r'^index/(?P<pid>\d+)$', views.index), url(r'^home/$', views.home), # 自定义分页专用 url(r'^home/(?P<pid>\d+)$', views.home), # 自定义分页专用 ]
2.views.py
第一行的模块导入为我们自定义的一个对数据分页处理操作的一个函数,这里简单说明下他的使用,
class Page(object):
def __init__(self,currout_page,num,data_count,url,page_num):
currout_page:当前页码
num:每页显示数据条数
data_count:数据总条数
url:跳转的url
page_num:每页跳转标签的个数
Page类中有三个函数
start() 根据用户给的当前页数,返回当前页数数据的开始索引
end() 根据用户给的当前页数,返回当前页数数据的结束索引
pagestr() 更加用户给定的参数,返回html标签,该html会生成上下页和页码信息
from utils import page def home(request,pid='1'): data_count = models.Host.objects.count() # 数据总条数 page_obj = page.Page(pid,10,data_count,'/home/',10) data_list = models.Host.objects.all()[page_obj.start():page_obj.end()] # 返回数据列表 return render(request,'home.html',{'data_list':data_list,'pagestr':page_obj.pagestr})
3 home.html 模板
模板通过 render 函数传过来的参数对模板进行渲染,生成分页信息,注意:Page类中pagestr返回给模板的为字符串信息,需要通过 模板语言的safe 方法来允许模板进行渲染。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css"> </head> <body> <div style="width: 800px;margin: 0 auto"> <table class="table table-hover"> <h1>主机列表</h1> <tr> <th>ID</th> <th>主机名</th> <th>IP</th> </tr> {% for obj in data_list %} <tr> <td>{{ obj.id }}</td> <td>{{ obj.hostname }}</td> <td>{{ obj.ip }}</td> </tr> {% endfor %} </table> <nav aria-label="..."> <ul class="pagination"> {{ pagestr|safe }} </ul> </nav> </div> </body> </html>
4. page.py
这个文件是我放到了最外层目录下的utils文件夹下。
在上面介绍views.py中的home函数时已经说过了函数的具体用法,这里就不在说明了。具体的实现请看下边函数内容。如有不足请指出。
#!/usr/bin/env python # -*- coding:utf-8 -*- class Page(object): def __init__(self,currout_page,num,data_count,url,page_num): currout_page = int(currout_page) if currout_page.isdigit() else 1 # 当前页 self.num = num # 每页显示的数据条数 a,b = divmod(data_count,num) # 数据总条数 if b == 0: self.page_count = a else: self.page_count = a + 1 self.currout_page = currout_page if 1<=currout_page<=a else 1 self.url = url self.page_num = page_num def start(self): return (self.currout_page - 1) * self.num def end(self): return self.currout_page * self.num def pagestr(self): pagestr = [] if self.currout_page > 1: top = '<li><a href="%s%s">上一页</a></li>'%(self.url,self.currout_page - 1) pagestr.append(top) if self.page_count <= self.page_num: for i in range(1,self.page_count): range_str = '<li><a href="%s%s">%s</a></li>'%(self.url,i,i) pagestr.append(range_str) else: if self.currout_page <= int(self.page_num/2): start = 1 end = self.page_num + 1 else: if self.currout_page < self.page_count - int(self.page_num/2): start = self.currout_page - int(self.page_num/2) end = self.currout_page + int(self.page_num/2) else: start = self.page_count - self.page_num end = self.page_count for i in range(start,end+1): if i == self.currout_page: range_str = '<li class="active"><a href="%s%s">%s</a></li>' % (self.url, i, i) pagestr.append(range_str) else: range_str = '<li><a href="%s%s">%s</a></li>'%(self.url,i,i) pagestr.append(range_str) if self.currout_page < self.page_count: buttom = '<li><a href="%s%s">下一页</a></li>'%(self.url,self.currout_page + 1) pagestr.append(buttom) return ''.join(pagestr)
2 Form
Form 有两个功能,一个是数据验证,一个是可以生成html。
2.1 Form 验证
数据到数据库的流程一般为如下,用户输入数据,提交后台,后台写入,返回结果给前端。没错。
这里就涉及到数据的正确性,数据是否使我们想要的格式,这样一来就需要做判断。。。。。。
前端判断 可以减少错误数据发送到后端,但后端为了保险起见,还要检验下数据是否可用,真麻烦。。。。然而From就可以帮你来验证数据是否可用。
之前的思路是,点击一个button,跳转到一个新的页面,在新的页面中添加并提交数据,数据在前端和后台都进行下验证,然后写入数据库并返回执行结果
but , 现在有了Django的Form验证,一切变得简单。
---------------------------------------------------开始来了解下Form的基本用法-----------------------------------------------------------------------
from django import forms from django.forms import fields class HostInfo(forms.Form): hostname = fields.CharField( required=True, error_messages={'required':'hostname不能为空'}, ) ip = fields.GenericIPAddressField( error_messages={'required': 'IP不能为空','invalid':'IP格式错误'}, ) user_id = fields.IntegerField( error_messages={'required': 'User_id不能为空'}, )
使用Form需要通过继承forms.Form来定义一个类,调用类中自己定义的来验证数据是否正确
看上边的代码说下Form的基本使用,
1.继承forms.Form来定义一个类
2.类中包含需要验证的字段必须和前端传到后端的关键字一样,他是根据关键字来对应的。
3.如果用户数据的信息有误,Form会给我们返回错误信息,错误信息为英文,如果想修改为中文,需要使用error_messages来重新定义错误信息
Form中的方法:
1. obj = HostInfo(request.POST)
定义一个Form类的时候需要传入参数,传入参数为request.POST,这样这个函数就会自动帮你验证用户提交的数据。
2. obj.is_valid()
返回bool值,表示传入的数据是否验证成功,成功返回True,失败返回False
3. obj.cleaned_data()
如果用户输入数据验证通过,通过cleaned_data函数会把数据以字典的形式返回
4. obj.errors用户的错误信息
包含用户验证没有通过的错误信息,可以通过obj.errors['hostname'][0]来获取关于hostname的第一条错误信息。
views.py文件内容
def add_host(request): if request.method == 'GET': return render(request,'add_host.html') elif request.method == 'POST': obj = HostInfo(request.POST) if obj.is_valid(): print(obj.cleaned_data) return render(request, 'add_host.html', {'obj': obj}) else: print(obj.errors) return render(request,'add_host.html',{'obj':obj})
add_host.html文件内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css"> </head> <body> <div style="width: 800px;margin: 0 auto"> <form method="post" action="/add_host/"> {% csrf_token %} <div class="form-group"> <label>Hostname</label> <input type="text" class="form-control" placeholder="Hostname" name="hostname"> {{ obj.errors.hostname.0 }} </div> <div class="form-group"> <label>IP</label> <input type="text" class="form-control" placeholder="IP" name="ip"> {{ obj.errors.ip.0 }} </div> <div class="form-group"> <label>User</label> <select name="user_id" id="user" class="form-control"> <option value="1">app-01</option> <option value="2">app-02</option> <option value="3">app-03</option> </select> {{ obj.errors.user_id.0 }} </div> <button type="submit" class="btn btn-default">提交</button> </form> </div> </body> </html>
上边这个版本的问题是无法保留用户上次的数据信息,原因是以为每次都是刷新页面,但并没有将用户数据的信息进行重新传值给模板
当然也可以自己来写,但是Form除了验证功能还有一个功能是用户生成HTML。利用Form的这个功能可以实现把用户输入的数据保留下来,并且渲染传给前端
2.2 Form 生成html
这里的代码是对添加信息做了用户输入信息的验证和错误提示,
views.py文件内容
from django.shortcuts import render from django.shortcuts import HttpResponse from django.shortcuts import redirect from app import models # Create your views here. def create(request): models.User.objects.create(username='helei',password='123') models.User.objects.create(username='alex',password='123') models.User.objects.create(username='egon',password='123') for i in range(1,201): models.Host.objects.create(hostname='www.%s.com'%i,ip='192.168.1.%s'%i,user_id=1) return HttpResponse('添加成功') # django模块实现分页 from django.core.paginator import Paginator def index(request,pid=1): obj_list = models.Host.objects.all() # 所有的数据对象 page_obj = Paginator(obj_list,10) # 定义一个分页对象实例 pages = page_obj.page(pid) # 传递页数给page_obj对象 return render(request,'index.html',{'pages':pages}) # pages.object_list 分页后的数据 # 自定义分页函数 from utils import page def home(request,pid='1'): data_count = models.Host.objects.count() # 数据总条数 page_obj = page.Page(pid,10,data_count,'/home/',10) data_list = models.Host.objects.all()[page_obj.start():page_obj.end()] # 返回数据列表 return render(request,'home.html',{'data_list':data_list,'pagestr':page_obj.pagestr}) from django import forms from django.forms import fields from django.forms import widgets class HostInfo(forms.Form): hostname = fields.CharField( required=True, # 设置为非空,默认非空 error_messages={'required':'hostname不能为空'}, # 定义错误提示 widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'用户名'}) # 定义生成的html类型及样式 ) ip = fields.GenericIPAddressField( error_messages={'required': 'IP不能为空','invalid':'IP格式错误'}, widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'密码'}) ) user_id = fields.IntegerField( error_messages={'required': 'User_id不能为空'}, widget=widgets.Select(attrs={'class': 'form-control'},choices=[(1,'app-01'),(2,'app-02'),(3,'app-03')]) ) def add_host(request): if request.method == 'GET': obj = HostInfo() return render(request, 'add_host.html', {'obj': obj}) elif request.method == 'POST': obj = HostInfo(request.POST) if obj.is_valid(): # 操作数据等其他操作 print('数据验证通过') else: print('数据错误') return render(request,'add_host.html',{'obj':obj})
add_host.html文件内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css"> </head> <body> <div style="width: 800px;margin: 0 auto"> <form method="post" action="/add_host/" novalidate> {% csrf_token %} <div class="form-group"> <label>Hostname</label> {{ obj.hostname }} {{ obj.errors.hostname.0 }} </div> <div class="form-group"> <label>IP</label> {{ obj.ip }} {{ obj.errors.ip.0 }} </div> <div class="form-group"> <label>User</label> {{ obj.user_id }} {{ obj.errors.user_id.0 }} </div> <button type="submit" class="btn btn-default">提交</button> </form> </div> </body> </html>
结合对数据库的操作来看看添加的数据是否成功:(上面代码中有些中文写错了。 主要点,下面这个都改好了。)
views.py文件内容
from django.shortcuts import render from django.shortcuts import HttpResponse from django.shortcuts import redirect from app import models # Create your views here. def create(request): models.User.objects.create(username='helei',password='123') models.User.objects.create(username='alex',password='123') models.User.objects.create(username='egon',password='123') for i in range(1,201): models.Host.objects.create(hostname='www.%s.com'%i,ip='192.168.1.%s'%i,user_id=1) return HttpResponse('添加成功') # django模块实现分页 from django.core.paginator import Paginator def index(request,pid=1): obj_list = models.Host.objects.all() # 所有的数据对象 page_obj = Paginator(obj_list,10) # 定义一个分页对象实例 pages = page_obj.page(pid) # 传递页数给page_obj对象 return render(request,'index.html',{'pages':pages}) # pages.object_list 分页后的数据 # 自定义分页函数 from utils import page def home(request,pid='1'): data_count = models.Host.objects.count() # 数据总条数 page_obj = page.Page(pid,10,data_count,'/home/',10) data_list = models.Host.objects.all().select_related().order_by('-id')[page_obj.start():page_obj.end()] # 返回数据列表 return render(request,'home.html',{'data_list':data_list,'pagestr':page_obj.pagestr}) from django import forms from django.forms import fields from django.forms import widgets class HostInfo(forms.Form): hostname = fields.CharField( required=True, # 设置为非空,默认非空 error_messages={'required':'hostname不能为空'}, # 定义错误提示 widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'主机名'}) # 定义生成的html类型及样式 ) ip = fields.GenericIPAddressField( error_messages={'required': 'IP不能为空','invalid':'IP格式错误'}, widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'IP地址'}) ) user_id = fields.IntegerField( error_messages={'required': 'User_id不能为空'}, widget=widgets.Select(attrs={'class': 'form-control'}, choices=[(1,'app-01'),(2,'app-02'),(3,'app-03')]) ) def __init__(self,*args,**kwargs): super(HostInfo,self).__init__(*args,**kwargs) self.fields['user_id'].widget.choices = models.User.objects.values_list('id', 'username') def add_host(request): if request.method == 'GET': obj = HostInfo() return render(request, 'add_host.html', {'obj': obj}) elif request.method == 'POST': obj = HostInfo(request.POST) if obj.is_valid(): # 操作数据等其他操作 ret = models.Host.objects.create(**obj.cleaned_data) print('数据验证通过') return redirect('/home/') else: print('数据错误') return render(request,'add_host.html',{'obj':obj})
add_host.html文件内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css"> </head> <body> <div style="width: 800px;margin: 0 auto"> <form method="post" action="/add_host/" novalidate> {% csrf_token %} <div class="form-group"> <label>Hostname</label> {{ obj.hostname }} {{ obj.errors.hostname.0 }} </div> <div class="form-group"> <label>IP</label> {{ obj.ip }} {{ obj.errors.ip.0 }} </div> <div class="form-group"> <label>User</label> {{ obj.user_id }} {{ obj.errors.user_id.0 }} </div> <button type="submit" class="btn btn-default">提交</button> </form> </div> </body> </html>
在user_id中widget=widgets.Select() 可以设置为下拉框,内有两个参数,attrs为设置下拉框的样式设置,choices是这是下拉框的默认参数,
如果设置为 choices = models.User.objects.values_list('id', 'username')
需要注意的是这里的默认设置只在程序运行的时候加载一次,如果与user_id关联的外键表数据有改变, 在添加页面的下拉框中内容时不会实时变化的。可以使用下列方法解决这个问题。
def __init__(self,*args,**kwargs):
super(HostInfo,self).__init__(*args,**kwargs)
self.fields['user_id'].widget.choices = models.User.objects.values_list('id', 'username')
# 通过重写重写父类的构造函数,使类在每次调用的时候都去数据库取值进行赋值加载
到这里,这个添加功能就算是写完了, 下面写下编辑的功能
"""test_s18 URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from app import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^create/$', views.create), url(r'^index/$', views.index), url(r'^index/(?P<pid>\d+)$', views.index), url(r'^home/$', views.home), # 自定义分页专用 url(r'^home/(?P<pid>\d+)$', views.home), # 自定义分页专用 url(r'^add_host/',views.add_host), url(r'^edit_host/(?P<hid>\d+)$',views.edit_host), ]
from django.shortcuts import render from django.shortcuts import HttpResponse from django.shortcuts import redirect from app import models # Create your views here. def create(request): models.User.objects.create(username='helei',password='123') models.User.objects.create(username='alex',password='123') models.User.objects.create(username='egon',password='123') for i in range(1,201): models.Host.objects.create(hostname='www.%s.com'%i,ip='192.168.1.%s'%i,user_id=1) return HttpResponse('添加成功') # django模块实现分页 from django.core.paginator import Paginator def index(request,pid=1): obj_list = models.Host.objects.all() # 所有的数据对象 page_obj = Paginator(obj_list,10) # 定义一个分页对象实例 pages = page_obj.page(pid) # 传递页数给page_obj对象 return render(request,'index.html',{'pages':pages}) # pages.object_list 分页后的数据 # 自定义分页函数 from utils import page def home(request,pid='1'): data_count = models.Host.objects.count() # 数据总条数 page_obj = page.Page(pid,10,data_count,'/home/',10) data_list = models.Host.objects.all().select_related().order_by('-id')[page_obj.start():page_obj.end()] # 返回数据列表 return render(request,'home.html',{'data_list':data_list,'pagestr':page_obj.pagestr}) from django import forms from django.forms import fields from django.forms import widgets class HostInfo(forms.Form): hostname = fields.CharField( required=True, # 设置为非空,默认非空 error_messages={'required':'hostname不能为空'}, # 定义错误提示 widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'主机名'}) # 定义生成的html类型及样式 ) ip = fields.GenericIPAddressField( error_messages={'required': 'IP不能为空','invalid':'IP格式错误'}, widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'IP地址'}) ) user_id = fields.IntegerField( error_messages={'required': 'User_id不能为空'}, widget=widgets.Select(attrs={'class': 'form-control'}, choices=[(1,'app-01'),(2,'app-02'),(3,'app-03')]) ) def __init__(self,*args,**kwargs): super(HostInfo,self).__init__(*args,**kwargs) self.fields['user_id'].widget.choices = models.User.objects.values_list('id', 'username') def add_host(request): if request.method == 'GET': obj = HostInfo() return render(request, 'add_host.html', {'obj': obj}) elif request.method == 'POST': obj = HostInfo(request.POST) if obj.is_valid(): # 操作数据等其他操作 print('数据验证通过') ret = models.Host.objects.create(**obj.cleaned_data) if ret: print('添加数据成功') else: print('添加数据失败') # 后期需要改进 return redirect('/home/') else: print('数据错误') return render(request,'add_host.html',{'obj':obj}) def edit_host(request,hid): if request.method == 'GET': userinfo = models.Host.objects.filter(id=hid).values('hostname','ip','user_id').first() obj=HostInfo(initial=userinfo) # 利用initial给HostInfo 赋值 print(obj) return render(request,'edit_host.html',{'obj':obj}) elif request.method == 'POST': obj = HostInfo(request.POST) if obj.is_valid(): # 操作数据等其他操作 print('数据验证通过') ret = models.Host.objects.filter(id=hid).update(**obj.cleaned_data) if ret: print('编辑数据成功') else: print('编辑数据失败') # 后期需要改进 return redirect('/home/') else: print('数据错误') return render(request,'add_host.html',{'obj':obj})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css"> </head> <body> <div style="width: 800px;margin: 0 auto"> <form method="post"> {% csrf_token %} <div class="form-group"> <label>Hostname</label> {{ obj.hostname }} {{ obj.errors.hostname.0 }} </div> <div class="form-group"> <label>IP</label> {{ obj.ip }} {{ obj.errors.ip.0 }} </div> <div class="form-group"> <label>用户</label> {{ obj.user_id }} {{ obj.errors.user_id.0 }} </div> <button type="submit" class="btn btn-default">提交</button> </form> </div> </body> </html>
字段类型:
fields字段类型: CharFiled() EmailField() IntegerField() GenericIPAddressField() FileField() # 上传文件的 fields.RegexField( regex='\d+' ) # 自定义 fields.ChoiceField() # 多选
字段中插件类型:
widgets插件 widgets.TextInput()
widgets.FileInput() widgets.TextPasswordInput() widgets.Textarea() widgets.Select() widgets.SelectMultiple()
widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))
http://www.cnblogs.com/wupeiqi/articles/6144178.html
http://www.cnblogs.com/wupeiqi/articles/6144178.html
3.中间件
#!/usr/bin/env python # -*- coding:utf-8 -*- from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class M1(MiddlewareMixin): def process_request(self,request): print('m1') def process_view(self, request, callback, callback_args, callback_kwargs): print('m1.process_view') def process_exception(self, request, exception): return HttpResponse('我给处理了') def process_response(self,request,response): print(response) print('m2') return response
http://www.cnblogs.com/wupeiqi/articles/5237704.html
待续中间件