征服django的關鍵內容

<!DOCTYPE html>


Django




css

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
html


運行

python manage.py runserver ip+端口
python


抽屜

- 抽屜
- 配置
mysql

  • 主站app
  • 後臺管理app


    建立app

    使用app時要在app_info裏添加app名稱,而且以逗號結尾
    python manage.py startapp 主站名

    python manage.py startapp 後臺管理名
    jquery


    app目錄:

    migrations 數據修改表結構

    admin Django提供的後臺管理

    apps 配置當前app
    models ORM,寫制定的類,經過命令建立數據庫結構

    tests 單元測試

    views 業務邏輯代碼
    nginx

  1. 配置模板的路徑

    TEMPLATES = [
    {
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [os.path.join(BASEDIR,'templates')],
    'APP
    DIRS': True,
    'OPTIONS': {
    'contextprocessors': [
    'django.template.contextprocessors.debug',
    'django.template.context
    processors.request',
    'django.contrib.auth.context
    processors.auth',
    'django.contrib.messages.contextprocessors.messages',
    ],
    },
    },
    ]
  2. 配置靜態路徑,配置以後就能夠直接訪問到,靜態文件就能生效
    STATICFILES
    DIRS=(
    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) #獲取請求發來的數據git


    #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'}) github

    {{currentuser}}

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

    {{currentuser}}

    </body>

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

    {{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 %}

    傳值

    def index(request): USERLIST={ 'k1':'root1', 'k2':'root2', 'k3':'root3', 'k4':'root4', } return render(request,'index.html',{'userlist':USER_LIST})
    正則表達式分組 url(r'^detail-(?P \d+)-(?P \d+).html', views.detail),#調用的時候就不分順序了
    def detail(request,nid,uid): return render(request,'detail.html',{'detail info':USERLIST[nid]})
    <!DOCTYPE html>

    詳細信息

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

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

    url(r'^detail-(?P \d+)-(?P \d+).html', views.detail),#調用的時候就部分順序了
    def func(request,**kwargs): kwargs={'nid':1,'uid':3}
    路由 name是對URL路由關係進行命名,之後根據此名稱生成本身想要的URL

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

    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/9 xxx.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 數據庫中字段的列名 dbtablespace default 數據庫中字段的默認值 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.name obj.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 title %}{% endblock %} {% 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

filter a. app下建立templatetags目錄 b. 任意xxoo.py文件 c. 建立template對象 register d. @register.filter def func(a1,a2) return "asdfasd" e. settings中註冊APP f. 頂部 {% 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) 一、獲取Cookie: request.COOKIES['key'] request.getsignedcookie(key, default=RAISEERROR, salt='', maxage=None) 參數: default: 默認值 salt: 加密鹽 maxage: 後臺控制過時時間 二、設置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傳輸cookie SESSIONCOOKIEHTTPONLY = 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或者viewfunckwargs from 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 }}

{% csrf token %}
{{ 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控件,而且添加樣式c1 from 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中可見

相關文章
相關標籤/搜索