标签:
一、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"]]
(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"> <div class="form_group"><input name="password" class="form-control" label=‘密码‘ type="password" placeholder="密码" require=‘true‘></div> </div> <div class="form_group"><input class="btn btn-info form_btn" type="submit" value="登录"></div> </form>
def login(request): if request.method == "POST": username = request.POST.get("username") password = request.POST.get("password") if username == "zhangsan" and password == "123456": request.session["IS_LOGIN"] = True #创建session return redirect("/app01/home/") return render(request,"app01/login.html") def home(request): islogin = request.session.get("IS_LOGIN",False) if islogin:#如果用户已登录 return render(request,"app01/menus.html") else: return redirect("/app01/login/") def logout(request):#退出 try: del request.session[‘IS_LOGIN‘] except KeyError: pass return redirect("/app01/login/")
更多:http://docs.30c.org/djangobook2/chapter14/
https://docs.djangoproject.com/en/1.9/ref/settings/#settings-sessions
五、Ajax
1、跨站请求伪造
django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成
GET 请求不需要 CSRF 认证,POST 请求需要正确认证才能得到正确的返回结果。一般在POST请求的表单中加入{% csrf_token %}
<form id="Form" method="post" action="/app01/login/"> {% csrf_token %} <input name=‘username‘ type="text"> <input name=‘password‘ type="password"> <input type="submit" value="登录"> </form>
veiw中设置返回值:
return render_to_response("app01/login.html",data,context_instance=RequestContext(request)) #或者 return render(request, "app01/login.html", data)
2、发送简单数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <input type="button" onclick="Ajaxsubmit();" value="提交"/> <script type="text/javascript" src="../../static/style/js/jquery-2.2.3.js"></script> <script> function Ajaxsubmit(){ var host = ‘127.0.0.1‘; var port = ‘8000‘; $.ajax({ url:"/app01/user_list/", type:‘POST‘, data:{h:host,p:port}, success:function(arg){ } }) } </script> </body> </html>
2、发送复杂数据类型
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <input type="button" onclick="Ajaxsubmit();" value="提交"/> <script type="text/javascript" src="../../static/style/js/jquery-2.2.3.js"></script> <script> function Ajaxsubmit(){ var userlist = [ {‘username‘:‘zhangsan‘,‘arg‘:18}, {‘username‘:‘lisi‘,‘arg‘:20}, ]; $.ajax({ url:"/app01/user_list/", type:‘POST‘, tradition: true, data:{data:JSON.stringify(userlist)},//序列化 success:function(arg){ var callback_dict = $.parseJSON(arg);//这里把字符串转换为对象 //然后咱们就可以判断 if(callback_dict.status){//如果为True执行失败 alert(‘提交成功‘) }else{//如果为False执行失败 alert(callback_dict.error) } } }); } </script> </body> </html>
views
def user_list(request): ret = {‘status‘:True,‘error‘:‘‘} try: print request.POST except Exception,e: ret[‘status‘] = False #如果出错就把ret[status] = False ret[‘error‘] = str(e) return HttpResponse(json.dumps(ret)) #返回ret字典
六、静态文件引用优化
在写项目时会导入很多静态文件,而有时要修改静态文件的目录名时就比较麻烦
原来导入方式
<script type="text/javascript" src="/static/style/js/jquery-2.2.3.js"></script>
优化
在settings的TEMPLATES里添加 ‘django.core.context_processors.static‘
TEMPLATES = [ { ‘BACKEND‘: ‘django.template.backends.django.DjangoTemplates‘, ‘DIRS‘: [os.path.join(BASE_DIR,‘templates‘),], ‘APP_DIRS‘: True, ‘OPTIONS‘: { ‘context_processors‘: [ ‘django.template.context_processors.debug‘, ‘django.template.context_processors.request‘, ‘django.contrib.auth.context_processors.auth‘, ‘django.contrib.messages.context_processors.messages‘, ‘django.core.context_processors.static‘, ], }, }, ]
优化后导入
<script type="text/javascript" src="{{ STATIC_URL }}style/js/jquery-2.2.3.js"></script>
这样要修改目录的话只需在配置文件里修改 STATIC_URL 就可以了
标签:
原文地址:http://www.cnblogs.com/melonjiang/p/5510943.html