Django进阶
Posted J_hong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django进阶相关的知识,希望对你有一定的参考价值。
一、Form
django中的Form一般有两种功能:1、输入html 2、验证用户输入
1、输入html
from django.shortcuts import render from django import forms class UserForm(forms.Form): host = forms.CharField() port = forms.CharField() email = forms.EmailField() mobile = forms.CharField() def user_list(request): obj = UserForm() return render(request,"index.html",{"obj":obj})
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/app01/user_list/"> <!--自动生成input标签--> <p>主机:{{ obj.host }}</p> <p>端口:{{ obj.port }}</p> <p>邮箱:{{ obj.email }}</p> <p>手机:{{ obj.mobile }}</p> <input type="submit"> </form> </body> </html>
2、验证
from django.shortcuts import render from django import forms class UserForm(forms.Form): host = forms.CharField() port = forms.CharField() email = forms.EmailField() mobile = forms.CharField() def user_list(request): obj = UserForm() if request.method == "POST": user_input_obj = UserForm(request.POST)#把提交过来的数据封装到UserForm,UserForm会自动把数据封装到user_input_obj if user_input_obj.is_valid(): #验证用户输入是否合法 data = user_input_obj.clean() #合法,获取数据 else: error_msg = user_input_obj.errors #不合法,返回错误信息 return render(request,"index.html",{"obj":user_input_obj,"error":error_msg}) return render(request,"index.html",{"obj":obj})
优化
def user_list(request): obj = UserForm(request.POST)#如果有数据,把提交过来的数据封装到UserForm,UserForm会自动把数据封装到user_input_obj if request.method == "POST": if obj.is_valid(): #验证用户输入是否合法 data = obj.clean() #合法,获取数据 else: error_msg = obj.errors.as_data() #不合法,返回错误信息 return render(request,"index.html",{"obj":obj,"error":error_msg}) return render(request,"index.html",{"obj":obj,})
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/app01/user_list/" method="post"> <!--自动生成input标签--> <p>主机:{{ obj.host }}<span>{{ error.host }}</span></p> <p>端口:{{ obj.port }}<span>{{ error.port }}</span></p> <p>邮箱:{{ obj.email }}<span>{{ error.email }}</span></p> <p>手机:{{ obj.mobile }}<span>{{ error.mobile }}</span></p> <input type="submit"> </form> </body> </html>
3、定制From表单
(1)设置报错信息,添加属性样式
class UserForm(forms.Form): host = forms.CharField(error_messages={"required":"主机不能为空"},#设置显示的错误信息 widget=forms.TextInput(attrs={"class":"form-control", "placeholder": "主机"})#添加属性和样式 ) port = forms.CharField() email = forms.EmailField() mobile = forms.CharField()
(2)多行文本框
#多行文本框,备注 memo = forms.CharField(required=False, #可以为空 widget=forms.Textarea(attrs={"class":"form-control", "placeholder": "备注"})#添加属性和样式 )
(3)下拉框
#下拉框 user_type_choice=( (0,"普通用户"), (1,"高级用户") ) user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice, attrs={\'class\': "form-control"}))
(4)动态生成select标签
文件中取数据
#动态下拉框 u_type = forms.IntegerField(widget=forms.widgets.Select( attrs={\'class\': "form-control"})) def __init__(self, *args, **kwargs): super(UserForm, self).__init__(*args, **kwargs) import json f=open("u_type_db") data = f.read() data_tuple = json.loads(data) self.fields[\'u_type\'].widget.choices = data_tuple
#u_type_db [[0, "AAA"], [1, "BBB"],[2,"CCC"]]
数据库中取数据
def __init__(self, *args, **kwargs): super(UserForm, self).__init__(*args, **kwargs) data_tuple=models.UserInfo.objects.all().values_list(\'id\',\'username\') self.fields[\'u_type\'].widget.choices = data_tuple
(5)自定义验证条件
#自定义验证 def mobile_validate(value): mobile_re = re.compile(r\'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$\') if not mobile_re.match(value): raise ValidationError(\'手机号码格式错误\') class UserForm(forms.Form): mobile = forms.CharField(validators=[mobile_validate, ])#添加自定义手机号验证
4、漂亮显示错误信息
def user_list(request): obj = UserForm() if request.method == "POST": user_input_obj = UserForm(request.POST)#把提交过来的数据封装到UserForm,UserForm会自动把数据封装到user_input_obj if user_input_obj.is_valid(): #验证用户输入是否合法 data = user_input_obj.clean() #合法,获取数据 else: error_msg = user_input_obj.errors #不合法,返回错误信息 return render(request,"index.html",{"obj":user_input_obj,"error":error_msg}) return render(request,"index.html",{"obj":obj,})
默认显示ul样式as_ul(),不美观
error_msg = user_input_obj.errors #不合法,返回错误信息
改成as_data()后只显示一个字符串格式
error_msg = user_input_obj.errors.as_data() #不合法,返回错误信息
方法:
定义
在html顶部调用
{% load form_tag %}
引用
<p>主机:{{ obj.host }}<span>{% error_message error.host %}</span></p>
as_json() 用于ajax返回
error_msg = user_input_obj.errors.as_json()#不合法,返回错误信息 return HttpResponse(error_msg )
实例:
html
{% load form_tag %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/app01/user_list/" method="post"> <!--自动生成input标签,也可以自己写html标签--> <p>主机:{{ obj.host }}<span>{% error_message error.host %}</span></p><!--引用--> <p>端口:{{ obj.port }}<span>{{ error.port }}</span></p> <p>邮箱:{{ obj.email }}<span>{{ error.email }}</span></p> <p>手机:{{ obj.mobile }}<span>{{ error.mobile }}</span></p> <p>备注:{{ obj.memo }}<span>{{ error.memo }}</span></p> <p>用户类型:{{ obj.user_type }}<span>{{ error.user_type }}</span></p> <input type="submit"> </form> </body> </html>
views
from django.shortcuts import render from django import forms import re from django.core.exceptions import ValidationError #自定义验证 def mobile_validate(value): mobile_re = re.compile(r\'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$\') if not mobile_re.match(value): raise ValidationError(\'手机号码格式错误\') class UserForm(forms.Form): host = forms.CharField(error_messages={"required":"主机不能为空"},#设置显示的错误信息 widget=forms.TextInput(attrs={"class":"form-control", "placeholder": "主机"})#添加属性和样式 ) port = forms.CharField(error_messages={"required":"端口不能为空"}) email = forms.EmailField(error_messages={"required":"邮箱不能为空"}) mobile = forms.CharField(error_messages={"required":"手机不能为空"}, validators=[mobile_validate, ])#添加自定义验证 #多行文本框,备注 memo = forms.CharField(required=False, #可以为空 widget=forms.Textarea(attrs={"class":"form-control", "placeholder": "备注"})#添加属性和样式 ) #下拉框 user_type_choice=( (0,"普通用户"), (1,"高级用户") ) user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice, attrs={\'class\': "form-control"})) def user_list(request): obj = UserForm() if request.method == "POST": user_input_obj = UserForm(request.POST)#把提交过来的数据封装到UserForm,UserForm会自动把数据封装到user_input_obj if user_input_obj.is_valid(): #验证用户输入是否合法 data = user_input_obj.clean() #合法,获取数据 else: error_msg = user_input_obj.errors.as_data() #不合法,返回错误信息 return render(request,"index.html",{"obj":user_input_obj,"error":error_msg}) return render(request,"index.html",{"obj":obj,})
二、中间件
1、django 中的中间件(middleware),其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件
MIDDLEWARE_CLASSES = [ #\'django.middleware.security.SecurityMiddleware\', \'django.contrib.sessions.middleware.SessionMiddleware\', \'django.middleware.common.CommonMiddleware\', #\'django.middleware.csrf.CsrfViewMiddleware\', \'django.contrib.auth.middleware.AuthenticationMiddleware\', \'django.contrib.auth.middleware.SessionAuthenticationMiddleware\', \'django.contrib.messages.middleware.MessageMiddleware\', \'django.middleware.clickjacking.XFrameOptionsMiddleware\', ]
中间件中可以定义四个方法,分别是:
process_request(self,request)
process_view(self, request, callback, callback_args, callback_kwargs)
process_exception(self, request, exception)
process_response(self, request, response)
每一个请求都是先通过中间件中的 process_request 函数,这个函数返回 None 或者 HttpResponse 对象,如果返回None ,继续处理其它中间件,如果返回一个 HttpResponse,就处理中止,返回到网页上
Django 会从 MIDDLEWARE_CLASSES 中按照从上到下的顺序一个个执行中间件中的 process_request 函数,而其中 process_response 函数则是最前面的最后执行。
2、自定义中间件
创建中间件
class RequestMiddleware(object): def process_request(self,request): print("process_request") def process_view(self, request, callback, callback_args, callback_kwargs): print("process_view") def process_exception(self, request, exception): print("process_exception") def process_response(self, request, response): print("process_response") return response class RequestMiddleware2(object): def process_request(self,request): print("process_request2") def process_view(self, request, callback, callback_args, callback_kwargs): print("process_view2") def process_exception(self, request, exception): print("process_exception2") def process_response(self, request, response): print("process_response2") return response
注册中间件
settings.py
MIDDLEWARE_CLASSES = [ #\'django.middleware.security.SecurityMiddleware\', \'django.contrib.sessions.middleware.SessionMiddleware\', \'django.middleware.common.CommonMiddleware\', #\'django.middleware.csrf.CsrfViewMiddleware\', \'django.contrib.auth.middleware.AuthenticationMiddleware\', \'django.contrib.auth.middleware.SessionAuthenticationMiddleware\', \'django.contrib.messages.middleware.MessageMiddleware\', \'django.middleware.clickjacking.XFrameOptionsMiddleware\', \'app01.middleware.middle.RequestMiddleware\', \'app01.middleware.middle.RequestMiddleware2\', ]
路由执行的函数
def index(request): print("index") return HttpResponse("index")
执行结果
上面是中间没有HttpResponse返回时的执行流程顺序,先执行process_request和process_view方法,在执行路由定义的函数,最后从最后一个process_response 开始执行,process_exception只会在出现异常时执行
三、缓存
1、由于Django是动态网站,一般来说需要实时地生成访问的网页,展示给访问者,这样,内容可以随时变化,但是从数据库读多次把所需要的数据取出来,要比从内存或者硬盘等一次读出来 付出的成本大很多。最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者Redis中,一定时间内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回。
settings配置
CACHES = { \'default\': { \'BACKEND\': \'django.core.cache.backends.filebased.FileBasedCache\',#表示利用文件系统缓存 \'LOCATION\': os.path.join(BASE_DIR, \'cache\'),#文件路径 \'TIMEOUT\': 600, \'OPTIONS\': { \'MAX_ENTRIES\': 1000 } } }
views
import time from django.shortcuts import HttpResponse,render from django.views.decorators.cache import cache_page @cache_page(60 * 15)#表示缓存15分钟 def index(request): data=time.time() return HttpResponse(data)
其它的一些内建可用的 Backends
\'django.core.cache.backends.db.DatabaseCache\' \'django.core.cache.backends.dummy.DummyCache\' \'django.core.cache.backends.filebased.FileBasedCache\' \'django.core.cache.backends.locmem.LocMemCache\' \'django.core.cache.backends.memcached.MemcachedCache\' \'django.core.cache.backends.memcached.PyLibMCCache\'
更多相关:http://djangobook.py3k.cn/2.0/chapter15/
四、Session和Cookie
cookie保存在客户端的电脑上,session保存与服务器
session用来在服务器端保存用户会话状态信息,依赖于cookies
操作session:
获取 session:request.session[key]
设置 session:reqeust.session[key] = value
删除 session:del request[key]
request.session.set_expiry(value)
value是个整数,session会在些秒数后失效。
value是个datatime或timedelta,session就会在这个时间后失效。
value是
0
,用户关闭浏览器session就会失效。
value是
None
,session会依赖全局session失效策略。
<form class="common_form" id="Form" method="post" action="/app01/login/"> <div><h1 class="login_title">登录</h1></div> <div style="width: 600px"> <div class="form_group"><input name="username" class="form-control" label=\'用户名\' type="text" placeholder="用户名" require=\'true\'></div> </div> <div style="width: 600px"> <以上是关于Django进阶的主要内容,如果未能解决你的问题,请参考以下文章python3-开发进阶Django-form组件中model form组件