1. 程式人生 > >征服django的關鍵內容

征服django的關鍵內容

關系 優點 reverse hello 下拉 name %20 反向 read

Django

django-admin startproject wjtest(項目名) 在命令行裏創建django項目wjtest - wjtest #對整個程序進行配置
- init
- settings #配置文件
- url #URL對應關系
- wsgi #遵循WSGI規範,程序正式上線用uwsgi+nginx
- manage.py #管理Django程序
- python manage.py
- python manage.py startapp xx
- python manage.py makemigrations
- python manage.py migrate

運行
python manage.py runserver ip+端口

抽屜
- 抽屜 - 配置
- 主站app
- 後臺管理app

創建app
使用app時要在app_info裏添加app名稱,並且以逗號結尾python manage.py startapp 主站名
python manage.py startapp 後臺管理名

app目錄:
migrations 數據修改表結構
admin Django提供的後臺管理
apps 配置當前app models ORM,寫制定的類,通過命令創建數據庫結構
tests 單元測試
views 業務邏輯代碼
1. 配置模板的路徑
TEMPLATES = [ { ‘BACKEND‘: ‘django.template.backends.django.DjangoTemplates‘, ‘DIRS‘: [os.path.join(BASEDIR,‘templates‘)], ‘APPDIRS‘: True, ‘OPTIONS‘: { ‘contextprocessors‘: [ ‘django.template.contextprocessors.debug‘, ‘django.template.contextprocessors.request‘, ‘django.contrib.auth.contextprocessors.auth‘, ‘django.contrib.messages.contextprocessors.messages‘, ], }, }, ]2. 配置靜態路徑,配置之後就可以直接訪問到,靜態文件就能生效 STATICFILESDIRS=( os.path.join(BASE_DIR,‘static‘),#必須有逗號隔開 )在setting中,middelrware裏註釋 csrf保證數據可以提交

def func(request): # request.method GET/POST # http://127.0.0.1:8000/home?nid=123&name=wj #request.GET.get(‘‘,None) #獲取請求發來的數據

#request.POST.get(‘‘,None)
#return HttpResponse(‘字符串‘)
#return render(request,‘HTML模板的路徑‘)
#return redirect(‘/只能填URL路徑‘)重定向
# return redirect(‘/login‘) 斜杠要有

模板渲染

  1. 特殊的模板語言--{{變量名}}--def func(request): return render(request,"index.html",{‘currentuser‘:‘wj‘})

    {{currentuser}}

  2. --for循環--def func(request): return render(request,"index.html",{‘currentuser‘:‘wj‘,‘userlist‘:[‘alex‘,‘eric‘]},‘userdict‘:{‘k1‘:‘v1‘,‘k2‘:‘v2‘})

    {{currentuser}}
      {% for li in userlist%}
    • li
    • {%endfor%} {{user
      list.1}} {{userlist.0}} {{userdict.k1}} {{user_dict.k2}}

    </body>

  3. 條件
    def func(request): return render(request,"index.html",{‘currentuser‘:‘wj‘,‘userlist‘:[‘alex‘,‘eric‘]},‘userdict‘:{‘k1‘:‘v1‘,‘k2‘:‘v2‘})

    {{currentuser}} {{userlist.1}} {{userlist.0}} {{userdict.k1}} {{userdict.k2}} {% if age %} 有年齡 {% if age > 8 %}一定加空格隔開 <a>老男人</a> {% else %} 小鮮肉 {% endif %} {% else %} 無年齡 {% endif %}

    </body>

    Django請求聲明周期
    -> URL對應關系(匹配)-> 視圖函數 -> 返回用戶字符串
    -> URL對應關系(匹配) -> 視圖函數 -> 打開一個HTML文件,讀取內容

路由系統,URL

1. url(r‘^index/‘,views.index),url(r‘^home/‘,views.Home.as_view())
2. url(r‘^detail-(\d+).html‘,views.detail),
3. url(r‘^detail-(?P<nid>\d+)-(?P<uid>\d+).html‘,views.detail)接收的時候用*args **kwargs,帶指定名的參數使用kwargs,沒有指定參數名使用args

視圖

request.body是所有方法的上層方法1. GET方法獲取數據 v=request.GET.get(‘sex‘)2. POST方法獲取數據 v=request.POST.get(‘sex‘)3. 取文件 obj=request.FILES.get(‘fafafa‘)# 取到文件對象提交的時候需要在html代碼裏要加,enctype="multipart/form-data"才能上傳文件 obj=request.FILES.get(‘fafafa‘)# 取到文件對象 print(type(obj)) print(obj.name)#文件名稱 import os filepath=os.path.join(‘upload‘,obj.name) f=open(filepath,‘wb‘) for i in obj.chunks(): #生成器 f.write(i) f.close() 文件對象=request.FILES.get()文件對象.name文件對象.size文件對象.chunks() 4. 兩種對應關系 FBV function base view url.py index->函數名
view.py 存函數
CBV class base view
from django.views import View class Home(View): def dispatch(self, request, *args, **kwargs): #調用父類裏的dispath result=super(Home,self).dispatch(request, *args, **kwargs) return result #發來get請求執行get方法 def get(self,request): print(request.method) return render(request,‘home.html‘) #發來post請求執行post方法 def post(self,request): print(request.method) return render(request,‘home.html‘)

 url(r‘^home/‘, views.Home.as_view()),
getlist用於checkbox多選時
  1. 裝飾器
  2. django模板語言循環字體

      {% for row in user_list.values %}
    • {{ row }}
    • {% endfor %}

    傳值

      {% for k,rwo in userdict.items %}
    • {{ rwo.name }}
    • {% endfor %}

    def index(request):USERLIST={ ‘k1‘:‘root1‘, ‘k2‘:‘root2‘, ‘k3‘:‘root3‘, ‘k4‘:‘root4‘,}return render(request,‘index.html‘,{‘userlist‘:USER_LIST})
    正則表達式分組url(r‘^detail-(?P

    詳細信息

    {{ detailinfo.name }}
    {{ detailinfo.email }}

    def func(request,args): args=(2,9)
    def func(request,args,
    kwargs): args=(1,9)

    url(r‘^detail-(?P

    url(r‘^indexx/‘, views.index,name=‘i1‘),
    url(r‘^home/(\d+)/‘,views.index,name=‘i2‘), url(r‘^login/(?P

    def func(request,args,*kwargs): from django.urls import reverse url1=reverse(‘i1‘) #indexx/ url2=reverse(‘i2‘,args(1,2,)) #home/1/2 url3=reverse(‘i3‘,kwargs={‘pid‘:1,‘nid‘:9}) #login/1/9xxx.html {% url ‘i1‘ %} {% url ‘i2‘ 1 2 %} {% url ‘i3‘ pid=1 nid=9 %}模板語言

    {% url ‘index‘ %}action="{% url ‘index‘ 3 %}"
    註: #當前URL
    request.path_info模板語言裏的使用


    from django.urls import reverse
    v=reverse(‘indexx‘,args=(90,80,)
    v=reverse(‘indexx‘,kwargs={‘nid‘:1,‘uid‘:99})action="{% url ‘index‘ nid=3 uid=3 %}"
    print(v)
    路由分發 匹配app名字from django.conf.urls import url,include
    urlpatterns=[ url(r‘^cmdb/‘,include(‘app01,urls‘)),#app01新建urls文件
    url(r‘^monitor/‘,include(‘app02,urls‘)), ]

模板

ORM操作

創建類
dbfirst先寫數據庫在寫程序 codefirst直接通過程序代碼生成數據庫 a. 寫類 from django.db import models # Create your models here. #app01userinfo class UserInfo(models.Model): #id列,自增,主鍵 #用戶名列,字符串類型,指定長度 username=models.CharField(maxlength=32) password=models.CharField(maxlength=64) b. 註冊 settings: installapps裏添加app名字 c. 執行 python manage.py makemigrations python manage.py migrate d.註意 Django默認使用MySQLdb模塊鏈接MySQL 主動修改為pymysql,在project同名文件夾下init文件中添加如下代碼 import pymysql pymysql.installasMySQLdb() 1. 根據類自動創建數據庫表 app下的models.py 2. 根據類對數據庫表中的數進行各種操作

    添加數據數據的三種方式
1.
# models.UserInfo.objects.create(
# username=‘root‘,
# password=‘123‘,
# )
2.
# obj=models.UserInfo(
# username=‘wj‘,
# password=‘321‘
# )
# obj.save()
3.
dic={
‘username‘:‘eric‘,
‘password‘:‘666‘
}
models.UserInfo.objects.create(**dic)

#查 返回的result的是個對象列表queryset
# result=models.UserInfo.objects.all()
# for row in result:
# print(row.id,row.username,row.password)
# result=models.UserInfo.objects.filter(username=‘root‘)#根據條件查詢 返回的也是列表
# result=models.UserInfo.objects.filter(username=‘root‘,passwrod=‘123‘)#根據條件查詢 返回的也是列表
# print(result)
result=models.UserInfo.objects.filter(username=‘root‘).first取出第一個對象
#刪除
# models.UserInfo.objects.filter(id=3).delete()
#更新
# models.UserInfo.objects.all().update(password=‘5678‘)
models.UserInfo.objects.filter(id=1).update(password=‘78‘)

修改表結構

  1. 第一種添加字段的方式在models裏添加一個字段,email=models.CharField(max_length=60),執行python manage.py makemigrations,會出現一個選項,選擇第一個,輸入字段的默認值,再執行python manage.py migrate就可以添加一個新的字段
  2. 第二種添加字段的方式gender=models.CharField(max_length=60,null=True),直接添加一個null參數默認它為True,這樣執行python manage.py makemigrations,python manage.py migrate新增加的gender字段就都默認為空字段。
  3. 刪除字段就直接再models裏註釋調字段。再執行就可一刪去字段
    創建超級用戶
    python manage.py createsuperuser
    字段:
    字符串類型
    數字
    時間
    二進制
    自增(必須加primarykey=True)
    字段的參數
    null 數據庫中字段是否可以為空db
    column 數據庫中字段的列名dbtablespacedefault 數據庫中字段的默認值primarykey 數據庫中字段是否為主鍵dbindex 數據庫中字段是否可以建立索引unique 數據庫中字段是否可以建立唯一索引uniquefordate 數據庫中字段【日期】部分是否可以建立唯一索引uniqueformonth 數據庫中字段【月】部分是否可以建立唯一索引uniqueforyear 數據庫中字段【年】部分是否可以建立唯一索引autonow ->創建時,自動生成時間
    autonowadd -> 更新時,自動更新為當前時間
    #obj=UserGroup.objects.filter(id=1).update(caption="CEO")
    #obj=UserGroup.objects.filter(id=1).first() #obj.caption="CEO"
    #obj.save()

    verbosename Admin中顯示的字段名稱,verbosename=用戶名blank Admin中是否允許用戶輸入為空editable Admin中是否可以編輯help_text Admin中該字段的提示信息choices Admin中顯示選擇框的內容,用不變動的數據放在內存中從而避免跨表操作,django admin中顯示下拉框,避免鏈表查詢 如:gf = models.IntegerField(choices=[(0, ‘何穗‘),(1, ‘大表姐‘),],default=1)

    errormessages 自定義錯誤信息(字典類型),從而定制想要顯示的錯誤信息; 字典健:null, blank, invalid, invalidchoice, unique, and uniquefordate 如:{‘null‘: "不能為空.", ‘invalid‘: ‘格式錯誤‘}

    validators 自定義錯誤驗證(列表類型),從而定制想要的驗證規則 from django.core.validators import RegexValidator from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\ MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator 如: test = models.CharField( maxlength=32, errormessages={ ‘c1‘: ‘優先錯信息1‘, ‘c2‘: ‘優先錯信息2‘, ‘c3‘: ‘優先錯信息3‘, }, validators=[ RegexValidator(regex=‘root\d+‘, message=‘錯誤了‘, code=‘c1‘), RegexValidator(regex=‘root112233\d+‘, message=‘又錯誤了‘, code=‘c2‘), EmailValidator(message=‘又錯誤了‘, code=‘c3‘), ] )
    外鍵
    usergroup=models.ForeignKey(‘UserGroup‘,to
    field=‘uid‘)#to
    field表示關聯字段,必須是唯一的
    usergroup=models.ForeignKey(‘UserGroup‘,tofield=‘uid‘,default=1)默認為UserGroup uid為1的對象
    兩種創建帶外鍵的模型數據,第二種方式好,只操作一次數據庫models.UserInfo.objects.create(username=‘root1‘,password=‘123‘,email=‘sfdfa‘,user
    group=models.UserGroup.objects.filter(id=1).first())models.UserInfo.objects.create(username=‘root1‘,password=‘123‘,email=‘sfdfa‘,usergroupid=1)獲取表單數據的三種方式

  4. 對象v1=models.Business.objects.all()QuerySet[obj(id,caption,code),obj(id,caption,code)...]
  5. 字典
    v2=models.Business.objects.all().values(‘id‘,‘caption‘)QuerySet[{‘id‘:1,‘caption‘:‘運維部‘},{‘id‘:1,‘caption‘:‘開發部‘}...]
  6. 元組v3=models.Business.objects.all().valueslist(‘id‘,‘caption‘)QuerySet[(1,運維部),(2,開發部)...]v1=models.Host.objexts.filter(nidgt=0)‘gt‘表示大於v2=models.Host.objexts.filter(nidgt=0).values(‘nid‘,‘hostname‘,‘bid‘,‘bcaption‘)其中bcaption是跨表查詢,所有的跨表查數據都用雙下劃線
    模板語言forlop.counter循環幾次就表示幾
    forlop.parentloop當有嵌套循環時,表示上層序號信息初識ajax
    $.ajax({ url:"/monitor/test_ajax/", type:"POST", data:{‘hostname‘:$(‘#hn‘).val(),‘ip‘:$(‘#ip‘).val(),‘port‘:$(‘#port‘).val(),‘caption‘:$(‘#cp‘).val()}, success:function(data){ if(data=="OK"){ location.reload() }else{ alert(data) } } })

    $.ajax({ url:"/monitor/testajax/", type:"POST", data:{‘hostname‘:$(‘#hn‘).val(),‘ip‘:$(‘#ip‘).val(),‘port‘:$(‘#port‘).val(),‘caption‘:$(‘#cp‘).val()}, success:function(data){ //data返回的是字符串 var obj = JSON.parse(data) if(obj.status){ location.reload() }else{ $(‘#errortext‘).text(obj.error) } } }) 服務器端永遠返回一個字典
    return HttpResponse(json.dumps(字典))models創建多對多 方式一:自定義關系表class Host(models.Model): nid=models.AutoField(primary
    key=True) hostname=models.CharField(maxlength=32,dbindex=True) ip=models.GenericIPAddressField(dbindex=True) port=models.IntegerField() b=models.ForeignKey(to=‘Business‘,tofield=‘id‘)class Application(models.Model): name=models.CharField(max_length=32)

    class HostToApp(models.Model): hobj=models.ForeignKey(to=‘Host‘,tofield=‘nid‘) aobj=models.ForeignKey(to=‘Application‘,tofield=‘id‘)
    方式二:自動創建關系表,無法對第三張表直接操作,可以間接操作
    class Host(models.Model): nid=models.AutoField(primarykey=True) hostname=models.CharField(maxlength=32,dbindex=True) ip=models.GenericIPAddressField(dbindex=True) port=models.IntegerField() b=models.ForeignKey(to=‘Business‘,tofield=‘id‘)class Application(models.Model): name=models.CharField(maxlength=32) h=models.ManyToManyField(‘Host‘)間接操作
    obj=Application.objexts.get(id=1)
    obj.nameobj.h.add(1)obj.h.add(2)obj.h.add(*[1,2,3,5])列表形式添加obj.h.remove(1)obj.h.remove([1,2,5])列表形式移除obj.h.clear()刪除obj.h.set([3,4,5])改不用加
    obj.h.all() 拿到host的queryset對象列表ajax傳遞多選,traditional為true,ajax方式不能跳轉,只能收到返回的字符串,如果想跳轉只能,location.reload,location.href="地址"$.ajax({ url: ‘/index/‘, data: {‘k‘: ‘v‘, ‘list‘: [1,2,3,4], ‘k3‘: JSON.stringfy({‘k1‘: ‘v‘}))}, $(form對象).serilize() type: ‘POST‘, dataType: ‘JSON‘: traditional: true, success:function(d){ location.reload() # 刷新 location.href = "某個地址" # 跳轉 } })知識點:URL

    Views 請求的其他信息 裝飾器Models在views.py中對應請求的方法裏的形參request,對應的類為WSGIRequest,WSGIRequest位置為如下位置,查看其中的方法

    from django.core.handlers.wsgi import WSGIRequest
    request.environ輸出所有信息for k,v in request.environ.items(): print(k,v)request.environ["HTTPUSERAGENT"]模板中也有自己的語言,該語言可以實現數據展示繼承下面是模板

<!DOCTYPE html>

{% block css %}{% endblock %}

小男孩管理

{% block content %}{% endblock %}{% block js %}{% endblock %}

繼承上面的代碼
{% extends ‘master.html‘ %}
{% block title %}
小男孩管理
{% endblock %}
{% block content %}
<h1>用戶管理</h1>
<ul>
{% for i in u %}
<li>{{ i }}</li>
{% endfor %}
</ul>
{% endblock %}
{% block css %}
<style>
body{
background-color: red;
}
</style>
{% endblock %}

{{ item }}{% for item in itemlist %} {{ item }} {% endfor %}  forloop.counter  forloop.first  forloop.last {% if orderedwarranty %} {% else %} {% endif %}母板:{% block title %}{% endblock %}子板:{% extends "base.html" %}   {% block title %}{% endblock %}幫助方法:{{ item.eventstart|date:"Y-m-d H:i:s"}}{{ bio|truncatewords:"30" }}{{ mylist|first|upper }}{{ name|lower }}
自定義simpletag自定義simpletag:第一步:在某個app下創建一個templatetags目錄(必須要的)
第二部:創建任意py文件第三步:創建template對象 register第四步:創建函數用@register.simple
tag裝飾 @register.simple
tag def func(a1,a2) return "abcd"第五步:settings中註冊app第六步:頂部 {% load py文件 %}缺點: 不能作為if條件優點: 參數任意

from django import template
from django.utils.safestring import mark_safe

register = template.Library()
@register.simple_tag
def my_simple_time(v1,v2,v3):
return v1 + v2 + v3

filtera. app下創建templatetags目錄b. 任意xxoo.py文件c. 創建template對象 registerd. @register.filter def func(a1,a2) return "asdfasd"e. settings中註冊APPf. 頂部 {% load xxoo %}g. {{ 參數1|函數名:"參數二,參數三" }} {{ 參數1|函數名:數字 }}缺點: 最多兩個參數,不能加空格優點: 能作為if條件 {% if "maliya"|wjj:"hello" %} {% endif %}

分頁(自定義的分頁) XSS攻擊是拿走你的cookie進行操作 XSS安全的兩種方式: 在html裏處理 {{ pagestr|safe }} 在後臺處理 from django.utils.safestring import marksafe pagestr=marksafe(pagestr)
Cookie操作:設置10秒後失效兩種方法 1. res.set
cookie(‘username‘,username,maxage=10) 2. import datetime currentdate=datetime.datetime.utcnow() current_date=currentdate+datetime.timedelta(seconds=10) res.setcookie(‘username‘,username,expires=currentdate)1、獲取Cookie:request.COOKIES[‘key‘]request.getsignedcookie(key, default=RAISEERROR, salt=‘‘, maxage=None) 參數: default: 默認值 salt: 加密鹽 maxage: 後臺控制過期時間2、設置Cookie:

rep = HttpResponse(...) 或 rep = render(request, ...)

rep.setcookie(key,value,...)rep.setsigned_cookie(key,value,salt=‘加密鹽‘,...) 參數: key, 鍵 value=‘‘, 值 maxage=None, 超時時間 expires=None, 超時時間(IE requires expires, so set it if hasn‘t been already.)datetime類型 path=‘/‘, Cookie生效的路徑,/ 表示根路徑,特殊的:跟路徑的cookie可以被任何url的頁面訪問,其余的都用不了 domain=None, Cookie生效的域名 secure=False, https傳輸 httponly=False 只能http協議傳輸,無法被JavaScript獲取(不是絕對,底層抓包可以獲取到也可以被覆蓋)由於cookie保存在客戶端的電腦上,所以,JavaScript和jquery也可以操作cookie。

<script src=‘/static/js/jquery.cookie.js‘>$.cookie("listpagernum", 30,{ path: ‘/‘ });cookie加密,salt對應字符串為加鹽。解密時也必須相同obj.setsignedcookie(‘username‘,‘kangbazi‘,salt=‘fajlfkd‘)request.getsignedcookie(‘username‘,salt="fajlfkd")

model操作(原生SQL)

表內容操作:
obj=models.TB(..)
obj.save()
models.TB.objects.all()[7:10]
models.TB.objecte.create()
models.TB.objects.create(**{})
models.TB.objects.all()
models.TB.objects.undate(..)
models.TB.objects.filter(..)
models.TB.objects.filter(id__in=[1,2,3])
models.TB.objects.filter(單下劃線id)
models.TB.objects.delete()
models.TB.objects.values()
models.TB.objects.get()
models.TB.objects.value_list()
models.TB.objects.filter().undate()
models.TB.objects.filter().first()
models.TB.objects.filter(**{})
models.TB.objects.filter(**{}).count()
models.TB.objects.filter(雙下劃線跨表)
models.TB.objects.filter(id__gt=1)雙下劃線gt表示大於
models.TB.objects.filter(id__range=[1,2])
models.TB.objects.filter(id__lt=1)小於
models.TB.objects.filter(id__lte=1)小於等於
models.TB.objects.filter(id__gte=1)大於等於
models.TB.objects.exclude(id__gte=1)不等於
多對多
obj.set
obj.add(1,2,3)
obj.add([1,2,3])
obj.remove([1,2,3])
obj.clear()
obj.all()..
models.TB.objects.all()
[obj,obj]
obj.fk.name

models.TB.objects.all().order_by(‘‘)
models.TB.objects.distinct()
模板語言
session
  1. Session基於cookie做用戶驗證時:敏感信息不適合放在cookie中a. Session原理 Cookie是保存在用戶瀏覽器端的鍵值對 Session是保存在服務器端的鍵值對 # 獲取、設置、刪除Session中數據 request.session[‘k1‘] request.session.get(‘k1‘,None) request.session[‘k1‘] = 123 request.session.setdefault(‘k1‘,123) # 存在則不設置 del request.session[‘k1‘]#刪除某個鍵值對

    # 所有 鍵、值、鍵值對
    request.session.keys()
    request.session.values()
    request.session.items()
    request.session.iterkeys()
    request.session.itervalues()
    request.session.iteritems()
    # 用戶session的隨機字符串
    request.session.session_key
    # 將所有Session失效日期小於當前日期的數據刪除
    request.session.clear_expired()
    # 檢查 用戶session的隨機字符串 在數據庫中是否
    request.session.exists("session_key")
    # 刪除當前用戶的所有Session數據
    request.session.delete("session_key")
    # 註銷使用
    request.session.clear()
    request.session.set_expiry(value)
    * 如果value是個整數,session會在些秒數後失效。
    * 如果value是個datatime或timedelta,session就會在這個時間後失效。
    * 如果value是0,用戶關閉瀏覽器session就會失效。
    * 如果value是None,session會依賴全局session失效策略。

    a. 關於session裏的配置 settings.py

    將數據放在緩存裏,不放在數據庫裏SESSIONENGINE = ‘django.contrib.sessions.backends.cache‘ # 引擎SESSIONCACHE_ALIAS = ‘default‘ # 使用的緩存別名(默認內存緩存,也可以是memcache),此處別名依賴緩存的設置

    SESSIONCOOKIENAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串SESSIONCOOKIEPATH = "/" # Session的cookie保存的路徑SESSIONCOOKIEDOMAIN = None # Session的cookie保存的域名SESSIONCOOKIESECURE = False # 是否Https傳輸cookieSESSIONCOOKIEHTTPONLY = True # 是否Session的cookie只支持http傳輸SESSIONCOOKIEAGE = 1209600 # Session的cookie失效日期(2周)SESSIONEXPIREATBROWSERCLOSE = False # 是否關閉瀏覽器使得Session過期SESSIONSAVEEVERY_REQUEST = False # 是否每次請求都保存Session,默認修改之後才保存,每次操作後,不是第一次操作開始算session依賴cookie

CSRF

CSRF驗證會驗證數據提交,
{% csrftoken %}可以看到每次與服務器溝通時發出的csrf,使用表單提交要在表單寫{% csrftoken %},
ajax提交數據時,兩種方式
1. 寫在這個script裏的所有ajax都可以執行
$.ajaxSetup( { beforeSend:function(xhr,settings){ xhr.setRequestHeader(‘X-CSRFtoken‘,$.cookie(‘csrftoken‘)); } });

  1. 單獨寫在ajax請求裏
    $(‘#btn1‘).click(function(){$.ajax({ url:‘/login/‘, type:‘POST‘, data:{‘user‘:‘root‘,‘pwd‘:‘123‘}, headers:{‘X-CSRFtoken‘:$.cookie(‘csrftoken‘)}, success:function(arg){

    }

    })})
    當訪問方法為GET時是不需要加token的,所以第二種方法的使用時可以做如下設置
    function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));}$.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } }});當在django框架中,setting裏註釋掉middle裏的csrf驗證,但有些方法需要使用csrf驗證時,可以使用裝飾器,
    from django.views.decorators.csrf import csrfexempt,csrfprotect
    在需要用的方法上使用裝飾器
    @csrf_protect
    def index(request):return render(request,‘index.html‘)

中間件

from django.utils.deprecation import MiddlewareMixin
在setting文件中,MIDDLEWARE=[]列表中設置MIDDLEWARE[‘Middle.m1,Row1‘,‘Middle.m1,Row2‘,‘Middle.m1,Row3‘,]執行順序,processrequest,processview,url-view,processresponse,如果請求裏有數據,會放到processview裏的viewfuncargs或者viewfunckwargsfrom django.utils.deprecation import MiddlewareMixin

class Row1(MiddlewareMixin): def process_request(self,request): print(‘zhangsan‘)

def process_view(self, request, view_func, view_func_args, view_func_kwargs):
print(‘lisi‘)

def process_response(self, request, response):
print(‘扛把子‘)
return response

from django.shortcuts import HttpResponse
class Row2(MiddlewareMixin):
def process_request(self,request):
print(‘wangxiaoer‘)
# return HttpResponse(‘走‘)


def process_view(self, request, view_func, view_func_args, view_func_kwargs):
print(‘張需要‘)
def process_response(self, request, response):
print(‘張三‘)
return response

class Row3(MiddlewareMixin):
def process_request(self,request):
print(‘李四‘)


def process_view(self, request, view_func, view_func_args, view_func_kwargs):
print(‘王二麻‘)
def process_response(self, request, response):
print(‘小淘氣‘)
return response
#views函數有錯誤時執行,處理exception時也是一層一層往上找
def process_exception(self, request, exception):
if isinstance(exception,ValueError):
return HttpResponse(‘出現異常》。。‘)
def process_template_response(self,request,response):
# 如果Views中的函數返回的對象中,具有render方法
print(‘-----------------------‘)
return response

views裏的方法,返回的類中有render方法,會在processremplateresponse時返回
class Foo: def render(self): return HttpResponse(‘OK‘)def test(request): print(‘沒帶錢‘) return Foo()

緩存

動態網站需要經常去請求數據,每次請求服務器就會從新計算,這樣消耗的時間比讀一個標準文件耗時要長,所以django采用緩存機制,將某在一定時間內不會更改的數據寫道緩存裏,這樣使用起來減少了耗時。

設置緩存

緩存系統需要一些設置才能使用。也就是必須告訴它你要把數據還存在數據庫,文件系統或者直接在內存中。這個決定很重要,他會決定你的緩存性能,這幾個系統緩存速度是不同的。緩存設置通過setting文件的CACHES配置來實現。

Memcached

Django支持的最快,最高效的緩存類型, Memcached 是一個全部基於內存的緩存服務,起初是為了解決LiveJournal.com負載來開發的,後來是由Danga開源出來的。 它被類似Facebook 和 維基百科這種網站使用,用來減少數據庫訪問,顯著的提高了網站的性能。
Memcached 是個守護進程,它被分配了單獨的內存塊。 它做的所有工作就是為緩存提供一個快速的添加,檢索,刪除的接口。 所有的數據直接存儲在內存中,所以它不能取代數據庫或者文件系統的使用。
在安裝 Memcached 後, 還需要安裝 Memcached 依賴模塊。Python 有不少Memcache模塊最為常用的是python-memcached and pylibmc兩個模塊.
需要在Django中使用Memcached時:
將 BACKEND 設置為 django.core.cache.backends.memcached.MemcachedCache 或者 django.core.cache.backends.memcached.PyLibMCCache (取決於你所選綁定memcached的方式)
將 LOCATION 設置為 ip:port 值,ip 是 Memcached 守護進程的ip地址, port 是Memcached 運行的端口。或者設置為 unix:path 值,path 是 Memcached Unix socket file的路徑.
在這個例子中,Memcached 運行在本地(127.0.0.1) 的11211端口,使用python-memcached(也就是需要這麽一個python插件) 綁定:

    CACHES = {
‘default‘: {
‘BACKEND‘: ‘django.core.cache.backends.memcached.MemcachedCache‘,
‘LOCATION‘: ‘127.0.0.1:11211‘,
}
}

這個例子中,Memcached 通過一個本地的Unix socket file/tmp/memcached.sock 來交互,也要使用python-memcached綁定:

CACHES = {
‘default‘: {
‘BACKEND‘: ‘django.core.cache.backends.memcached.MemcachedCache‘,
‘LOCATION‘: ‘unix:/tmp/memcached.sock‘,
}
}

Memcached有一個非常好的特點就是可以讓幾個服務的緩存共享。 這就意味著你可以在多臺機器上運行Memcached服務,這些程序將會把這幾個機器當做 同一個 緩存,從而不需要復制每個緩存的值在每個機器上。為了使用這個特性,把所有的服務地址放在LOCATION裏面,用分號隔開或者當做一個list。 這個例子,緩存共享在2個Memcached 實例中,IP地址為172.19.26.240 和 172.19.26.242,端口同為11211:CACHES = { ‘default‘: { ‘BACKEND‘: ‘django.core.cache.backends.memcached.MemcachedCache‘, ‘LOCATION‘: [ ‘172.19.26.240:11211‘, ‘172.19.26.242:11211‘, ] }}下面的這個例子,緩存通過下面幾個 Memcached 實例共享,IP地址為172.19.26.240 (端口 11211), 172.19.26.242 (端口 11212), and 172.19.26.244 (端口 11213):

CACHES = {
‘default‘: {
‘BACKEND‘: ‘django.core.cache.backends.memcached.MemcachedCache‘,
‘LOCATION‘: [
‘172.19.26.240:11211‘,
‘172.19.26.242:11212‘,
‘172.19.26.244:11213‘,
]
}
}

關於Memcached最後要說一點,基於內存的緩存有一個缺點:因為緩存數據是存儲在內存中的,所以如果你的服務器宕機數據就會丟失。還要明確, 內存不能替代常駐的數據存儲,所以不要把基於內存的緩存當成你唯一的數據存儲方式。毫無疑問的,沒有任何的Django緩存後臺應該被用來替代常駐存儲--它們要做的是緩存解決方案,而不是存儲方案--但是我們在這裏指出這一點是因為基於內存的緩存真的是非常的臨時。

Form

form可以做用戶驗證生成HTML請求(保留提交的數據)

from django import forms
class FM(forms.Form):
user=forms.CharField()#變量名必須與html定義的名字一樣 pwd=forms.CharField() email=forms.EmailField()
def fm(request): if request.method=="GET": return render(request,‘fm.html‘) elif request.method=="POST": obj=FM(request.POST) r1=obj.isvalid() print(r1) if r1:#提交數據成功
print(obj.cleaned
data) else: print(obj.errors) print(obj.errors.asjson())#當輸入郵箱等格式不對時會報錯 return redirect(‘/fm/‘)
class FM(forms.Form):
user=forms.CharField(errormessage={‘required‘:"用戶名不能為空"})#變量名必須與html定義的名字一樣 pwd=forms.CharField(maxlength=12,min
length=6,errormessages={‘required‘:‘用戶名不能為空‘,‘minlength‘:‘密碼長度不能小於6‘,‘maxlength‘:‘密碼長度不能大於12‘) email=forms.EmailField(errormessage={‘required‘:‘郵箱不能為空‘,‘invalid‘:‘郵箱格式錯誤‘})
obj.erros繼承自ErrorDict是一個字典,所以輸出錯誤信息形式為obj.errors[‘user‘]

{% csrftoken %}

{{ obj.user }} {{obj.erros.user.0 }}

{{ obj.user }} {{obj.erros.pwd.0 }}

{{ obj.user }} {{obj.erros.email.0 }}

{% csrftoken %}
{{ obj.asp }}或者{{obj.asul}}或者{{ obj.astable }}

def fm(request): if request.method=="GET": obj=FM() return render(request,‘fm.html‘,{‘obj‘:obj}) elif request.method=="POST": obj=FM(request.POST) r1=obj.isvalid() print(r1) if r1:#提交數據成功
print(obj.cleaned
data) else: print(obj.errors) print(obj.errors.as
json())#當輸入郵箱等格式不對時會報錯 return render(request,‘fm.html‘,{‘obj‘:obj})
from django.forms import widgets
class FM(forms.Form): user=forms.CharField(...,widgets=widgets.Textarea(attrs={‘class‘:‘c1‘})#將user變成textarea控件,並且添加樣式c1from django.forms import fiels
#fiels代之字段class FM(forms.Form): user=filds.CharField(errormessage={‘required‘:"用戶名不能為空"})#變量名必須與html定義的名字一樣 pwd=filds.CharField(maxlength=12, minlength=6, errormessages={‘required‘:‘用戶名不能為空‘,‘minlength‘:‘密碼長度不能小於6‘,‘maxlength‘:‘密碼長度不能大於12‘}, widget=widgets.PasswordInput )

email=filds.EmailField(error_message={‘required‘:‘郵箱不能為空‘,‘invalid‘:‘郵箱格式錯誤‘})    

上傳文件 cleaned_data對應的f
下拉框
city = files.ChoiceField( choice=[(0,‘上海‘),(1,‘廣州‘),(2,‘東莞‘)])
多選框
city=files.MultipleChoiceField( choice=[(0,‘上海‘),(1,‘廣州‘),(2,‘東莞‘)]) www.cnblogs.com/wupeiqi/articles/6144178.html||6216618.html

model補充

#表單  
#app01_user
class User(models.Model):
name=models.CharField(max_length=32,db_index=True)
email=models.CharField(max_length=32,db_index=True)#創建索引時會生成索引文件
class Meta:
#數據庫生成的表名 默認 app名稱+下劃線+小寫類名
db_table=‘tb1‘
#生成一個索引文件,兩個索引都能用
index_together=[
("name","email"),
]
#最做前綴模式,在用戶名密碼驗證的時候可用,沒人會直接用密碼驗證
#select * from where name="XX"可以命中
select * from where name=‘xx‘ and email=‘xx‘可以命中
select * from where email=‘xx‘ #無法命中
聯合唯一索引
unique_together=((‘name‘,‘email‘))聯合索引唯一
在admin表中
verbose_name=‘user‘ 表名會是users
verbose_name_plural=‘user‘ 表名會是user
省內存空間的辦法
比如中國北京海澱區這是一個長的地址,村內存浪費空間,我們可以使用外鍵,並定義國家表,省市表,區表,然後存儲的時候只存儲對應代表的id就可以

一對多/一對一/多對多

ForeignKey(ForeignObject) # ForeignObject(RelatedField)
to, # 要進行關聯的表名
to_field=None, # 要關聯的表中的字段名稱
on_delete=None, # 當刪除關聯表中的數據時,當前表與其關聯的行的行為
- models.CASCADE,刪除關聯數據,與之關聯也刪除
- models.DO_NOTHING,刪除關聯數據,引發錯誤IntegrityError
- models.PROTECT,刪除關聯數據,引發錯誤ProtectedError
- models.SET_NULL,刪除關聯數據,與之關聯的值設置為null(前提FK字段需要設置為可空)
- models.SET_DEFAULT,刪除關聯數據,與之關聯的值設置為默認值(前提FK字段需要設置默認值)
- models.SET,刪除關聯數據,
a. 與之關聯的值設置為指定值,設置:models.SET(值)
b. 與之關聯的值設置為可執行對象的返回值,設置:models.SET(可執行對象)
def func():
return 10
class MyModel(models.Model):
user = models.ForeignKey(
to="User",
to_field="id"
on_delete=models.SET(func),)
related_name=None, # 反向操作時,使用的字段名,用於代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None, # 反向操作時,使用的連接前綴,用於替換【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values(‘表名__字段名‘)
limit_choices_to=None, # 在Admin或ModelForm中顯示關聯數據時,提供的條件:
# 如:
- limit_choices_to={‘nid__gt‘: 5}
- limit_choices_to=lambda : {‘nid__gt‘: 5}
from django.db.models import Q
- limit_choices_to=Q(nid__gt=10)
- limit_choices_to=Q(nid=8) | Q(nid__gt=10)
- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption=‘root‘)
db_constraint=True # 是否在數據庫中創建外鍵約束
parent_link=False # 在Admin中是否顯示關聯數據

v=UserType.objectes.all()for item in v: item.name item.id item.userset.all()反向查找
創建超級用戶
python manage.py createsuperuser
在models裏的ForeignKey類型類裏,默認初識使用limit
choiceto={‘id_gt‘:5}可以做id大於5的篩選條件,在admin中可見

征服django的關鍵內容