久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Django的一些學(xué)習(xí)demo說明

 容心居 2020-04-28

Web框架之Django:

(1)簡介:

Django是一個(gè)由Python寫成開源的重量級(jí)Web應(yīng)用框架,,采用MTV的框架模式,。它最初是被開發(fā)來用于管理勞倫斯出版集團(tuán)旗下的一些以新聞內(nèi)容為主的網(wǎng)站的,即是CMS(內(nèi)容管理系統(tǒng))軟件,。并于2005年7月在BSD許可證下發(fā)布,。這套框架是以比利時(shí)的吉普賽爵士吉他手Django Reinhardt來命名的。Django的優(yōu)勢在于:大而全,框架本身集成了ORM,、模型綁定,、模板引擎、緩存,、Session等諸多功能,。

(2)Django的處理流程:

blob.png
  1. 當(dāng)用戶發(fā)出HTTP請求,,URLhandler接收用戶請求,,根據(jù)開發(fā)人員設(shè)置的路由規(guī)則匹配相應(yīng)的處理類
    
  2. 根據(jù)請求的類型判斷調(diào)用的HTTP方法
    
  3. 如果需要連接數(shù)據(jù)庫,Views中的函數(shù)將會(huì)調(diào)用Models的方法,,否則直接去Template中取出HTML頁面直接返回
    
  4. 調(diào)用Models的時(shí)候,,Models會(huì)去數(shù)據(jù)庫讀取數(shù)據(jù)再返回給Views
    
  5. 經(jīng)過渲染頁面一起將最終的HTML頁面返回給頁面
    

☆MTV與MVC:

MTV和MVC的思想是一樣的的,只是思想的體現(xiàn)有所不同,。

MVC:M管理應(yīng)用程序的狀態(tài),,并約束改變狀態(tài)的行為,一般叫做業(yè)務(wù)規(guī)則,;V負(fù)責(zé)把數(shù)據(jù)格式化后呈現(xiàn)給用戶查看,;C接收用戶操作,根據(jù)訪問模型獲取數(shù)據(jù),,并調(diào)用視圖顯示這些數(shù)據(jù),,控制器(處理器)用于將模型與視圖隔離并成為二者之間的聯(lián)系紐帶。

MTV:M代表數(shù)據(jù)存取層,,也就是Model,,改成處理與數(shù)據(jù)相關(guān)的所有事務(wù)如何存取,如何驗(yàn)證數(shù)據(jù)的有效性,,包含哪些行為與數(shù)據(jù)相關(guān),;T指的是表現(xiàn)層,該層處理與現(xiàn)實(shí)相關(guān)的行為,,如何在頁面文檔中顯示數(shù)據(jù),,展現(xiàn)內(nèi)容,也就是Template,;V代表業(yè)務(wù)邏輯層,,該層包含存取模型及調(diào)取恰當(dāng)模板的相關(guān)邏輯。

☆Django版的MTV:

Django也是一個(gè)MVC框架,。但是在Django中,,控制器接受用戶輸入的部分由框架自行處理,所以 Django 里更關(guān)注的是模型(Model),、模板(Template)和視圖(Views),,稱為 MTV模式。

☆Django設(shè)計(jì)MVC優(yōu)美哲學(xué):

1.對象關(guān)系映射 (ORM,object-relational mapping):

以Python類形式定義你的數(shù)據(jù)模型,ORM將模型與關(guān)系數(shù)據(jù)庫連接起來,,你將得到一個(gè)非常容易使用的數(shù)據(jù)庫API,,同時(shí)你也可以在Django中使用原始的SQL語句。

2.URL 分派:

使用正則表達(dá)式匹配URL,,你可以設(shè)計(jì)任意的URL,,沒有框架的特定限定。像你喜歡的一樣靈活,。

3.模版系統(tǒng):

使用Django強(qiáng)大而可擴(kuò)展的模板語言,,可以分隔設(shè)計(jì)、內(nèi)容和Python代碼,。并且具有可繼承性,。

4.表單處理:

你可以方便的生成各種表單模型,實(shí)現(xiàn)表單的有效性檢驗(yàn),??梢苑奖愕膹哪愣x的模型實(shí)例生成相應(yīng)的表單。

5.Cache系統(tǒng):

可以掛在內(nèi)存緩沖或其它的框架實(shí)現(xiàn)超級(jí)緩沖一一實(shí)現(xiàn)你所需要的粒度,。

6.會(huì)話(session):

用戶登錄與權(quán)限檢查,,快速開發(fā)用戶會(huì)話功能。

7.國際化:

內(nèi)置國際化系統(tǒng),,方便開發(fā)出多種語言的網(wǎng)站,。

8.自動(dòng)化的管理界面:

不需要你花大量的工作來創(chuàng)建人員管理和更新內(nèi)容。Django自帶一個(gè)ADMIN site,類似于內(nèi)容管理系統(tǒng)

(3)Django的常用命令:

django-admin startproject sitename # 在當(dāng)前目錄下創(chuàng)建一個(gè)Django程序

python manage.py runserver ip:port # 啟動(dòng)服務(wù)器,,默認(rèn)是127.0.0.1:8000

python manage.py startapp appname # 創(chuàng)建APP

python manage.py syncdb# 同步數(shù)據(jù)庫,,Django 1.7及以上版本需要用以下的命令:

python manage.py makemigrations # 創(chuàng)建數(shù)據(jù)配置文件,顯示并記錄所有數(shù)據(jù)的改動(dòng)

python manage.py migrate #創(chuàng)建表結(jié)構(gòu),,將改動(dòng)更新到數(shù)據(jù)庫

python manage.py createsuperuser # 創(chuàng)建超級(jí)管理員

python manage.py dbshell # 數(shù)據(jù)庫命令行

python manage.py # 查看命令列表

(4)Django數(shù)據(jù)庫相關(guān):

☆默認(rèn)使用SQLite3數(shù)據(jù)庫的配置:

DATABASES = {

'default': {

    'ENGINE': 'django.db.backends.sqlite3',

    'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

}

}

☆MySQL的配置:

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.mysql',

'NAME':'',   # 數(shù)據(jù)庫應(yīng)該以utf-8編碼以支持中文

'USER': '',

'PASSWORD': '',

'HOST': '',

'PORT': '',

}

}

由于Python開發(fā)常用Python3.x,,Django連接數(shù)據(jù)庫的時(shí)候使用的是MySQL的MySQLdb模塊,然而在Python3中還沒有此模塊,,因此需要使用pymysql進(jìn)行代替,,下面的配置代碼寫入到項(xiàng)目目錄的init.py中即可:

import pymysql

pymysql.install_as_MySQLdb()

☆PostgreSQL數(shù)據(jù)庫的配置:

DATABASES = {

'default': {

    'NAME': '',

    'ENGINE': 'django.db.backends.postgresql_psycopg2',

    'USER': '',

    'PASSWORD': ''

}

☆Oracle數(shù)據(jù)庫的配置:

DATABASES = {

'default': {

    'ENGINE': 'django.db.backends.oracle',

    'NAME': '',

    'USER': 'r',

    'PASSWORD': '',

    'HOST': '',

    'PORT': '',

}

}

Django框架對于開發(fā)者而言高度透明化,對于不同數(shù)據(jù)庫的具體使用方法是一致的,,改變數(shù)據(jù)庫類型只需要變動(dòng)上述配置即可,。

☆Django中的Model數(shù)據(jù)庫操作:

Django提供了一個(gè)抽象層(“Model”)來構(gòu)建和管理Web應(yīng)用程序的數(shù)據(jù)。Django中遵循 Code Frist 的原則,,即:根據(jù)代碼中定義的類來自動(dòng)生成數(shù)據(jù)庫表,。關(guān)系對象映射(Object Relational Mapping,簡稱ORM),。

創(chuàng)建Django項(xiàng)目后的目錄結(jié)構(gòu):

.

├── app0 # app應(yīng)用目錄

│ ├── admin.py

│ ├── apps.py

│ ├── init.py

│ ├── migrations

│ │ └── init.py

│ ├── models.py

│ ├── tests.py

│ └── views.py

├── DjangoAllNotes # 與項(xiàng)目同名的項(xiàng)目目錄

│ ├── init.py

│ ├── pycache

│ │ ├── init.cpython-36.pyc

│ │ └── settings.cpython-36.pyc

│ ├── # 公用的Django配置文件

│ ├── urls.py

│ └── wsgi.py

├── manage.py

└── template

★創(chuàng)建基本表結(jié)構(gòu):

在Django中,,每一張數(shù)據(jù)表就是一個(gè)類,,這些類存在于每個(gè)app目錄的models.py文件中,執(zhí)行 python manage.py makemigrations 會(huì)根據(jù)models.py生成配置文件,,再執(zhí)行 python manage.py migrate 將會(huì)連接數(shù)據(jù)庫并創(chuàng)建表結(jié)構(gòu),。

file:models.py

from django.db import models

Create your models here.

class UserInfo(models.Model):

username = models.CharField(max_length=32)

password = models.CharField(max_length=64)

age = models.IntegerField()

email = models.EmailField()

other = models.TextField()

執(zhí)行命令:

D:\Codes\Python\DjangoAllNotes>python manage.py makemigrations

Migrations for 'app0':

app0\migrations\0001_initial.py

- Create model UserInfo

D:\Codes\Python\DjangoAllNotes>python manage.py migrate

Operations to perform:

Apply all migrations: admin, app0, auth, contenttypes, sessions

Running migrations:

Applying contenttypes.0001_initial... OK

Applying auth.0001_initial... OK

Applying admin.0001_initial... OK

Applying admin.0002_logentry_remove_auto_add... OK

Applying app0.0001_initial... OK

Applying contenttypes.0002_remove_content_type_name... OK

Applying auth.0002_alter_permission_name_max_length... OK

Applying auth.0003_alter_user_email_max_length... OK

Applying auth.0004_alter_user_username_opts... OK

Applying auth.0005_alter_user_last_login_null... OK

Applying auth.0006_require_contenttypes_0002... OK

Applying auth.0007_alter_validators_add_error_messages... OK

Applying auth.0008_alter_user_username_max_length... OK

Applying sessions.0001_initial... OK

D:\Codes\Python\DjangoAllNotes>

可視化如下:

blob.png

其他的字段參數(shù):

1.null = True # 數(shù)據(jù)庫字段是否可以為空

2.blank = True # django的 Admin 中添加數(shù)據(jù)時(shí)是否可允許空值

3.primary_key = False # 主鍵,對AutoField設(shè)置主鍵后,,就會(huì)代替原來的自增 id 列

4.auto_now # 自動(dòng)創(chuàng)建,,無論添加或修改,都是當(dāng)前操作的時(shí)間

5.auto_now_add # 自動(dòng)創(chuàng)建永遠(yuǎn)是創(chuàng)建時(shí)的時(shí)間

6.選擇:

GENDER_CHOICE = (

(u'男',u'Male'),

(u'女',u'Female'),

)

gender = models.CharField(max_length=2,choices = GENDER_CHOICE)

7.max_length # 長度,,是CharField必須屬性

8.default # 默認(rèn)值

9.verbose_name # Admin中字段的顯示名稱

10.name|db_column # 數(shù)據(jù)庫中的字段名稱

11.unique = True # 不允許重復(fù)

12.db_index = True # 數(shù)據(jù)庫索引

13.editable = True # 在Admin中是否可以編輯

14.error_messages = None # 錯(cuò)誤提示

15.auto_created = False # 自動(dòng)創(chuàng)建

16.help_text # 在Admin中提示幫助信息

17.validators = []

18.upload-to

其他的字段:

1.models.AutoField

自增列,,int類型,如果沒有設(shè)置,,默認(rèn)會(huì)生成一個(gè)名稱為id的列,,如果要顯示一個(gè)自定義的自增列,,必須將其設(shè)置為主鍵

2.models.CharField

字符串字段,,必須設(shè)置max_length屬性

3.models.BooleanField

布爾類型,在數(shù)據(jù)庫中的類型使用tinyint類型構(gòu)造實(shí)現(xiàn),,不能為空

4.models.ComaSeparatedIntegerField

用逗號(hào)分割的數(shù)字,,在數(shù)據(jù)庫中是varchar類型,繼承自CharField,,所以必須 max_lenght 屬性

5.models.DateField

日期類型,,在數(shù)據(jù)庫中對應(yīng)date類型,auto_now = True 則每次更新都會(huì)更新這個(gè)時(shí)間,;auto_now_add 則只是第一次創(chuàng)建添加,,之后的更新不再改變。

6.models.DateTimeField

日期類型,,在數(shù)據(jù)庫中對應(yīng)datetime,,auto_now = True 則每次更新都會(huì)更新這個(gè)時(shí)間;auto_now_add 則只是第一次創(chuàng)建添加,,之后的更新不再改變,。

7.models.Decimal

十進(jìn)制小數(shù)類型,在數(shù)據(jù)庫中對應(yīng)decimal類型,,必須指定整數(shù)位max_digits和小數(shù)位decimal_places

8.models.EmailField

字符串類型(正則表達(dá)式郵箱),,在數(shù)據(jù)庫中對應(yīng)varchar類型

9.models.FloatField

浮點(diǎn)類型,在數(shù)據(jù)庫中對應(yīng)double類型

10.models.IntegerField

整型,,在數(shù)據(jù)庫中對應(yīng)int類型

11.models.BigIntegerField

長整形

12.integer_field_ranges = {

'SmallIntegerField': (-32768, 32767),

'IntegerField': (-2147483648, 2147483647),

'BigIntegerField': (-9223372036854775808, 9223372036854775807),

'PositiveSmallIntegerField': (0, 32767),

'PositiveIntegerField': (0, 2147483647),

}

13.models.IPAddressField

字符串類型(ip4正則表達(dá)式)

14.models.GenericIPAddressField

字符串類型(ip4和ip6是可選的),,參數(shù)protocol可以是:both、ipv4,、ipv6,,驗(yàn)證時(shí),,會(huì)根據(jù)設(shè)置報(bào)錯(cuò)

15.models.NullBooleanField

允許為空的布爾類型

16.models.PositiveIntegerFiel

正數(shù)范圍的Integer

17.models.PositiveSmallIntegerField

正數(shù)范圍的smallInteger

18.models.SlugField

減號(hào)、下劃線,、字母,、數(shù)字

19.models.SmallIntegerField

數(shù)字,數(shù)據(jù)庫中的字段有:tinyint,、smallint,、int、bigint

20.models.TextField

字符串,,在數(shù)據(jù)庫中對應(yīng)longtext

21.models.TimeField

時(shí)間 HH:MM[:ss[.uuuuuu]]

22.models.URLField

字符串,,地址正則表達(dá)式

23.models.BinaryField

二進(jìn)制

24.models.ImageField

圖片

25.models.FilePathField

文件

元數(shù)據(jù):

db_table = ‘TableName’# 數(shù)據(jù)庫中生成的名稱,使用app名稱+下劃線+類名

index_tohether = [(‘pub_date’,’deadline’)] # 聯(lián)合索引

unique_together = ((‘drive’,’ restaurant’)) # 聯(lián)合唯一索引

verbose_name admin中顯示的名稱

觸發(fā)Model中的驗(yàn)證和錯(cuò)誤提示有兩種方式:

1.DjangoAdmin中的錯(cuò)誤信息會(huì)優(yōu)先根據(jù)Admin內(nèi)部的ModelForm錯(cuò)誤信息提示,,如果都成功,,才會(huì)再驗(yàn)證Model的字段并顯示指定的錯(cuò)誤信息。

更改Admin中的錯(cuò)誤提示:

from django.contrib import admin

Register your models here.

file:admin.py

from django.contrib import admin

from app0 import models

from django import forms

class UserInfoForm(forms.ModelForm):

username = forms.CharField(error_messages={'required': '用戶名不能為空.'})

email = forms.EmailField(error_messages={'invalid': '郵箱格式錯(cuò)誤.'})

age = forms.IntegerField(initial=1, error_messages={'required': '請輸入數(shù)值.', 'invalid': '年齡必須為數(shù)值.'})

class Meta:

    model = models.UserInfo

    fields = "__all__"

class UserInfoAdmin(admin.ModelAdmin):

form = UserInfoForm

admin.site.register(models.UserInfo, UserInfoAdmin)

2.調(diào)用Model對象的clean_fields方法:

file:models.py

class UserInfo(models.Model):

nid = models.AutoField(primary_key=True)

username = models.CharField(max_length=32)

email = models.EmailField(error_messages={'invalid': '格式錯(cuò).'})

file:views.py

def index(request):

obj = models.UserInfo(username='11234', email='uu')

try:

   print(obj.clean_fields())

except Exception as e:

   print(e)

return HttpResponse('ok')

Model的clean方法是一個(gè)鉤子,,可用于定制操作,,如:上述的異常處理。

★連表操作:

一對多:models.ForeignKey(其他表)

多對多:models.ManyToManyField(其他表)

一對一:models.OneToOneField(其他表)

1.一對多:

ForeignKey(ForeignObject) # ForeignObject(RelatedField)

to, # 要進(jìn)行關(guān)聯(lián)的表名

to_field=None, # 要關(guān)聯(lián)的表中的字段名稱

on_delete=None, # 當(dāng)刪除關(guān)聯(lián)表中的數(shù)據(jù)時(shí),,當(dāng)前表與其關(guān)聯(lián)的行的行為

  • models.CASCADE,,刪除關(guān)聯(lián)數(shù)據(jù),與之關(guān)聯(lián)也刪除

  • models.DO_NOTHING,,刪除關(guān)聯(lián)數(shù)據(jù),,引發(fā)錯(cuò)誤IntegrityError

  • models.PROTECT,刪除關(guān)聯(lián)數(shù)據(jù),,引發(fā)錯(cuò)誤ProtectedError

  • models.SET_NULL,,刪除關(guān)聯(lián)數(shù)據(jù),與之關(guān)聯(lián)的值設(shè)置為null(前提FK字段需要設(shè)置為可空)

  • models.SET_DEFAULT,,刪除關(guān)聯(lián)數(shù)據(jù),,與之關(guān)聯(lián)的值設(shè)置為默認(rèn)值(前提FK字段需要設(shè)置默認(rèn)值)

  • models.SET,刪除關(guān)聯(lián)數(shù)據(jù),,

a. 與之關(guān)聯(lián)的值設(shè)置為指定值,,設(shè)置:models.SET(值)

b. 與之關(guān)聯(lián)的值設(shè)置為可執(zhí)行對象的返回值,設(shè)置:models.SET(可執(zhí)行對象)

一對一:

OneToOneField(ForeignKey)

to, # 要進(jìn)行關(guān)聯(lián)的表名

to_field=None # 要關(guān)聯(lián)的表中的字段名稱

on_delete=None, # 當(dāng)刪除關(guān)聯(lián)表中的數(shù)據(jù)時(shí),,當(dāng)前表與其關(guān)聯(lián)的行的行為

一對一其實(shí)就是 一對多 + 唯一索引,,當(dāng)兩個(gè)類之間有繼承關(guān)系時(shí),默認(rèn)會(huì)創(chuàng)建一個(gè)一對一字段,。

多對多:

ManyToManyField(RelatedField)

to, # 要進(jìn)行關(guān)聯(lián)的表名

related_name=None, # 反向操作時(shí),,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()

related_query_name=None, # 反向操作時(shí),,使用的連接前綴,,用于替換【表名】 如: models.UserGroup.objects.filter(表名字段名=1).values('表名字段名')

limit_choices_to=None, # 在Admin或ModelForm中顯示關(guān)聯(lián)數(shù)據(jù)時(shí),,提供的條件

★表的增刪改查:

1.對數(shù)據(jù)進(jìn)行增加數(shù)據(jù):

-- coding:utf-8 --

file:views.py

from django.shortcuts import render, HttpResponse

Create your views here.

def home(request):

from app01 import models

models.UserInfo.objects.create(username='haha', password='123', age=20)

return HttpResponse('Home, 創(chuàng)建數(shù)據(jù)完成.')

1.1也可以直接傳入字典創(chuàng)建:

def home(request):

from app01 import models

dic = {

   'username':'tom',

   'password':'123',

   'age':18,

}

models.UserInfo.objects.create(**dic)

return HttpResponse('Home, 創(chuàng)建數(shù)據(jù)成功.')

2.刪除數(shù)據(jù):

def home(request):

from app01 import models

models.UserInfo.objects.filter(username='tom').delete()

3.修改數(shù)據(jù):

def home(request):

from app01 import models

models.UserInfo.objects.filter(age=20).update(age=22)

models.UserInfo.objects.all().update(age=22)   # 修改全部數(shù)據(jù)

4.查詢數(shù)據(jù):

def home(request):

from app01 import models

list = models.UserInfo.objects.all()  # 獲取全部數(shù)據(jù)

models.UserInfo.objects.filter(username='tom').first()   # 獲取第一條數(shù)據(jù)

獲取的數(shù)據(jù)是個(gè)列表,querySet類型,。

for item ini list:       # 遍歷列表

   print(item.username)

★使用雙下劃線連接操作:

1.獲取個(gè)數(shù):

models.Tb1.objects.filter(name='seven').count()

2.比較大?。?/p>

models.Tb1.objects.filter(id__gt=1) # 獲取id大于1的值

models.Tb1.objects.filter(id__gte=1) # 獲取id大于等于1的值

models.Tb1.objects.filter(id__lt=10) # 獲取id小于10的值

models.Tb1.objects.filter(id__lte=10) # 獲取id小于10的值

models.Tb1.objects.filter(id__lt=10, id__gt=1) # 獲取id大于1 且 小于10的值

3.是否包含:

models.Tb1.objects.filter(id__in=[11, 22, 33])

models.Tb1.objects.exclude(id__in=[11, 22, 33]) # 相當(dāng)于not in

4.是否為空:

Entry.objects.filter(pub_date__isnull=True)

  1. contains:

models.Tb1.objects.filter(name__contains="ven")

models.Tb1.objects.filter(name__icontains="ven")#icontains大小寫不敏感

models.Tb1.objects.exclude(name__icontains="ven")

  1. range范圍:

models.Tb1.objects.filter(id__range=[1, 2]) # 相當(dāng)于SQL中的between and

7.其他的操作:

startswith,istartswith, endswith, iendswith,

  1. order by:

models.Tb1.objects.filter(name='seven').order_by('id') # asc

models.Tb1.objects.filter(name='seven').order_by('-id') # desc

  1. group by:

from django.db.models import Count, Min, Max, Sum

models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))

相當(dāng)于:SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

  1. limit ,、offset:

models.Tb1.objects.all()[10:20]

  1. regex正則匹配,,iregex 不區(qū)分大小寫:

Entry.objects.get(title__regex=r'^(An?|The) +')

Entry.objects.get(title__iregex=r'^(an?|the) +')

12.日期:

Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))

Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))

13.年月日周時(shí)分秒:

Entry.objects.filter(pub_date__year=2005)

Entry.objects.filter(pub_date__year__gte=2005)

Entry.objects.filter(pub_date__month=12)

Entry.objects.filter(pub_date__month__gte=6)

Entry.objects.filter(pub_date__day=3)

Entry.objects.filter(pub_date__day__gte=3)

Entry.objects.filter(pub_date__week_day=2)

Entry.objects.filter(pub_date__week_day__gte=2)

Entry.objects.filter(timestamp__hour=23)

Entry.objects.filter(time__hour=5)

Entry.objects.filter(timestamp__hour__gte=12)

Entry.objects.filter(timestamp__minute=29)

Entry.objects.filter(time__minute=46)

Entry.objects.filter(timestamp__minute__gte=29)

Entry.objects.filter(timestamp__second=31)

Entry.objects.filter(time__second=2)

Entry.objects.filter(timestamp__second__gte=31)

14.extra:

extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None),有些情況下,,Django的查詢語法難以簡單的表達(dá)復(fù)雜的 WHERE 子句,,對于這種情況, Django 提供了 extra() QuerySet 修改機(jī)制,它能在 QuerySet生成的SQL從句中注入新子句,。無論何時(shí)你都需要非常小心的使用extra(). 每次使用它時(shí),,您都應(yīng)該轉(zhuǎn)義用戶可以使用params控制的任何參數(shù),以防止SQL注入***,。由于產(chǎn)品差異的原因,,這些自定義的查詢難以保障在不同的數(shù)據(jù)庫之間兼容(因?yàn)槟闶謱?SQL 代碼的原因),而且違背了 DRY 原則,,所以如非必要,,還是盡量避免寫 extra,。

Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))

Entry.objects.extra(where=['headline=%s'], params=['Lennon'])

Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])

Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])

★F和Q:

from django.db.models import F

models.Tb1.objects.update(num=F('num')+1) #F用于拿到原始數(shù)據(jù)

##方式一:

from django.db.models import Q

con = Q()

q1 = Q()

q2 = Q()

q1.connecter = 'OR'

q1.children.append(('id', 1))

q1.children.append(('id', 2))

q1.children.append(('id', 3))

q2.children.append(('c1', 10))

q2.children.append(('c1', 23))

q2.children.append(('c1', 12))

con.add('q1', 'AND')

con.add('q1', 'AND')

models.Tb.objects.filter(con)

##方式二:

Q(nid__gt=10)

Q(nid=8) | Q(nid__gt=10)

Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')

★執(zhí)行原生SQL:

from django.db import connection, connections

cursor = connection.cursor()

其實(shí)是cursor = connections['default'].cursor()

cursor.execute("""SELECT * from auth_user where id = %s""", [1])

row = cursor.fetchone()

★利用雙下劃線和 _set 將表之間的操作連接起來:

1.創(chuàng)建表結(jié)構(gòu):

from django.db import models

Create your models here.

class UserProfile(models.Model):

user_info = models.OneToOneField('UserInfo')

username = models.CharField(max_length=64)

password = models.CharField(max_length=64)

def __unicode__(self):

    return self.username

class UserInfo(models.Model):

user_type_choice = (

    (0, u'普通用戶'),

    (1, u'高級(jí)用戶'),

)

user_type = models.IntegerField(choices=user_type_choice)

name = models.CharField(max_length=32)

email = models.CharField(max_length=32)

address = models.CharField(max_length=128)

def __unicode__(self):

    return self.name

class UserGroup(models.Model):

caption = models.CharField(max_length=64)

user_info = models.ManyToManyField('UserInfo')

def __unicode__(self):

    return self.caption

class Host(models.Model):

hostname = models.CharField(max_length=64)

ip = models.GenericIPAddressField()

user_group = models.ForeignKey('UserGroup')

def __unicode__(self):

    return self.hostname

2.一對一操作:

user_info_obj = models.UserInfo.objects.filter(id=1).first()

print user_info_obj.user_type

print user_info_obj.get_user_type_display()

print user_info_obj.userprofile.password

user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()

print user_info_obj.keys()

print user_info_obj.values()

3.一對多操作:

dic = {

"hostname": "名字1",

"ip": "192.168.1.1",

"user_group_id": 1,   # 加對象則為"user_group"

}

models.Host.objects.create(**dic)

正向查找一對多

host_obj = models.Host.objects.all()

print(type(host_obj),host_obj)

<class 'django.db.models.query.QuerySet'>

<QuerySet [<Host: 名字1>]>

for item in host_obj:

print(item.hostname)

print(item.user_group.caption)

print(item.user_group.user_info.values())

<QuerySet [{'name': 'nick', 'user_type': 1, 'id': 1, 'email': '[email protected]', 'address': '128號(hào)'}]>

usergroup_obj = models.Host.objects.filter(user_group__caption='標(biāo)題1')

print(usergroup_obj)

反向查找一對多

usergroup_obj = models.UserGroup.objects.get(id=1)

print(usergroup_obj.caption)

ret = usergroup_obj.host_set.all() # 所有關(guān)于id=1的host

print(ret)

obj = models.UserGroup.objects.filter(host__ip='192.168.1.1').values('host__id', 'host__hostname')

print(obj)

<QuerySet [{'host__id': 1, 'host__hostname': '名字1'}]>

4.多對多操作:

user_info_obj = models.UserInfo.objects.get(name='nick')

user_info_objs = models.UserInfo.objects.all()

group_obj = models.UserGroup.objects.get(caption='CTO')

group_objs = models.UserGroup.objects.all()

添加數(shù)據(jù)

group_obj.user_info.add(user_info_obj)

group_obj.user_info.add(*user_info_objs)

刪除數(shù)據(jù)

group_obj.user_info.remove(user_info_obj)

group_obj.user_info.remove(*user_info_objs)

添加數(shù)據(jù)

user_info_obj.usergroup_set.add(group_obj)

user_info_obj.usergroup_set.add(*group_objs)

刪除數(shù)據(jù)

user_info_obj.usergroup_set.remove(group_obj)

user_info_obj.usergroup_set.remove(*group_objs)

獲取數(shù)據(jù)

print group_obj.user_info.all()

print group_obj.user_info.all().filter(id=1)

獲取數(shù)據(jù)

print user_info_obj.usergroup_set.all()

print user_info_obj.usergroup_set.all().filter(caption='CTO')

print user_info_obj.usergroup_set.all().filter(caption='DBA')

添加多對多

userinfo_id_1 = models.UserInfo.objects.filter(id=1)

usergroup_id_1 = models.UserGroup.objects.filter(id=1).first()

usergroup_id_1.user_info.add(*userinfo_id_1)

(5)Django路由系統(tǒng):

Django的路由系統(tǒng)本質(zhì)就是URL正則與調(diào)用的視圖函數(shù)之間的映射表,,URL的加載是從配置中開始的。

這樣Django也就很好的支持了靜態(tài)路由,,基于正則的動(dòng)態(tài)路由,,以及二級(jí)路由,同樣開發(fā)人員也可以自行使用基于請求方法的路由,。

urlpatterns = [

url(正則表達(dá)式, view函數(shù), 參數(shù), 別名),

Some...

]

參數(shù)是可選的要傳遞給視圖函數(shù)的默認(rèn)參數(shù)(字典形式)

別名也是可選的

例如:

urlpatterns = [

url(r'^admin/', admin.site.urls),

url(r'^one',views.one2one),

url(r'^two',views.one2many),

url(r'^three',views.many2many),

]

其他使用正則的例子:

urlpatterns = [

url(r'^articles/2003/$', views.special_case_2003),

url(r'^articles/([0-9]{4})/$', views.year_archive),

url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),

url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),

]

說明:

1.要捕獲從URL中的值,,用括號(hào)括起來,會(huì)當(dāng)參數(shù)傳入 views 視圖,。

2.沒有必要添加一個(gè)斜線,,因?yàn)槊總€(gè)URL都有。例如,,它articles不是/articles,。

3.在'r'前面的每個(gè)正則表達(dá)式字符串中是可選的,但建議,。它告訴Python字符串是“原始” -沒有什么字符串中應(yīng)該進(jìn)行轉(zhuǎn)義,。

使用正則分組:

urlpatterns = [

url(r’^index\d{2}/$’,views.index),

url(r’^index2/(?P<id>\d{3})/$’,views.index2),

url(r’^index3/(?P<id>\d{3})/(?P<name>\w+)’,views.index3),

]

def index(request):

return HttpResponse(‘OK’)

def index2(request, id):

print(“id=”+str(id))

return HttpResponse(‘OK’)

def index3(request, id, name):

print(“id=”+str(id))

print(“name=”+str(name))

return HttpResponse(‘OK’)

Django的二級(jí)路由示例:

extra_patterns = [

url(r'^reports/$', credit_views.report),

url(r'^reports/(?P<id>[0-9]+)/$', credit_views.report),

url(r'^charge/$', credit_views.charge),

]

from django.conf.urls import include, url

urlpatterns = [

url(r'^$', main_views.homepage),

url(r'^help/', include('apps.help.urls')), # 這里是個(gè)文件

url(r'^credit/', include(extra_patterns)),

]

URLconfs 有一個(gè)鉤子可以讓你加入一些額外的參數(shù)到view函數(shù)中:

from django.conf.urls import url

from . import views

urlpatterns = [

url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),

]

需要注意的是,當(dāng)你加上參數(shù)時(shí),,對應(yīng)函數(shù)views.year_archive必須加上一個(gè)參數(shù),,參數(shù)名也必須命名為 foo,,這樣就實(shí)現(xiàn)了參數(shù)名的靜態(tài)綁定,放置參數(shù)順序出錯(cuò),。

(6)Django的View視圖函數(shù):

HTTP中產(chǎn)生的兩大對象:

HTTP請求:HttpRequest

HTTP應(yīng)答:HttpResponse

☆HttpRequest對象:

當(dāng)請求一個(gè)HTML頁面的時(shí)候,,Django將會(huì)創(chuàng)建一個(gè)HttpRequest對象包含原數(shù)據(jù)的請求,然后Django加載適合的視圖,,通過HTTPRequest作為視圖函數(shù)的一地個(gè)參數(shù),。每個(gè)視圖負(fù)責(zé)返回一個(gè)HttpResponse響應(yīng)。

HttpRequest對象的屬性:

1.path:請求頁面的全路徑,,不包括域名

2.method:請求中使用的HTTP方法的字符串表示,。全大寫表示。例如

if req.method=="GET":

Some...

elseif req.method=="POST":

Some...

GET:包含所有HTTP GET參數(shù)的類字典對象

POST:包含所有HTTP POST參數(shù)的類字典對象

服務(wù)器收到空的POST請求的情況也是可能發(fā)生的,,也就是說,,表單form通過HTTP POST方法提交請求,但是表單中可能沒有數(shù)據(jù),,因此不能使用if req.POST來判斷是否使用了HTTP POST 方法,;應(yīng)該使用if req.method=="POST"。

3.COOKIES:包含所有cookies的標(biāo)準(zhǔn)Python字典對象,;keys和values都是字符串,。

4.FILES:包含所有上傳文件的類字典對象;FILES中的每一個(gè)Key都是<input type="file" name="" />標(biāo)簽中 name屬性的值,,F(xiàn)ILES中的每一個(gè)value同時(shí)也是一個(gè)標(biāo)準(zhǔn)的python字典對象,,包含下面三個(gè)Keys:

filename:上傳文件名,用字符串表示

content_type:上傳文件的Content Type

content:上傳文件的原始內(nèi)容

5.user:是一個(gè)django.contrib.auth.models.User對象,,代表當(dāng)前登陸的用戶,。如果訪問用戶當(dāng)前沒有登陸,user將被初始化為django.contrib.auth.models.AnonymousUser的實(shí)例,??梢酝ㄟ^user的is_authenticated()方法來辨別用戶是否登陸:

if req.user.is_authenticated();

只有激活Django中的AuthenticationMiddleware時(shí)該屬性才可用,。

6.session:唯一可讀寫的屬性,,代表當(dāng)前會(huì)話的字典對象;自己有激活Django中session支持時(shí)該屬性才可用,。

7.META:一個(gè)標(biāo)準(zhǔn)的Python字典包含所有可用的HTTP頭,。可用標(biāo)題取決于客戶端和服務(wù)器,,一些例子:

CONTENT_LENGTH – 請求體的長度(一個(gè)字符串),。

CONTENT_TYPE – 請求體的類型。

HTTP_ACCEPT - 為響應(yīng)–可以接受的內(nèi)容類型,。

HTTP_ACCEPT_ENCODING – 接受編碼的響應(yīng)

HTTP_ACCEPT_LANGUAGE – 接受語言的反應(yīng)

HTTP_HOST – 客戶端發(fā)送的HTTP主機(jī)頭,。

HTTP_REFERER – 參考頁面

HTTP_USER_AGENT – 客戶端的用戶代理字符串,。

QUERY_STRING – 查詢字符串,作為一個(gè)單一的(分析的)字符串,。

REMOTE_ADDR – 客戶端的IP地址

REMOTE_HOST – 客戶端的主機(jī)名

REMOTE_USER – 用戶通過Web服務(wù)器的身份驗(yàn)證,。

REQUEST_METHOD – 字符串,如"GET"或"POST"

SERVER_NAME – 服務(wù)器的主機(jī)名

SERVER_PORT – 服務(wù)器的端口(一個(gè)字符串),。

☆HttpResponse對象屬性:

對于HtppResponse對象來說,,是由Django自動(dòng)創(chuàng)建的牡丹石HTTPResponse對象必須開發(fā)人員手動(dòng)創(chuàng)建,每個(gè)View請求處理方法必須返回一個(gè)HTTPResponse對象,。

HTTPResponse對象常用的方法:

1.頁面渲染,,render,render_to_response,推薦使用render,,因?yàn)閞ender功能更為強(qiáng)大,。

2.頁面跳轉(zhuǎn),redirect

3.頁面?zhèn)鲄?,locals,,可以直接將對應(yīng)視圖中的所有變量全部傳遞給模板。

示例代碼:

def HandlerName(request):

Some...

var0, var1 = 1, 2

Some...

return render_to_response(‘Home.html’, locals())

對于render的:

render(request, template_name, context=None, content_type=None, status=None, using=None)

結(jié)合給定的模板與一個(gè)給定的上下文,,返回一個(gè)字典HttpResponse在渲染文本對象,。

request和template_name是必須參數(shù),request指的是傳來的resquest,,template_name指的是HTML模板或模板序列的名稱,,如果給定的是序列,那么序列中的第一個(gè)模板將被引用,。

context 一組字典的值添加到模板中,。默認(rèn)情況下,這是一個(gè)空的字典,。

content_type MIME類型用于生成文檔。

status 為響應(yīng)狀態(tài)代碼,。默認(rèn)值為200

using 這個(gè)名字一個(gè)模板引擎的使用將模板,。

(7)Django模板和模板語言:

要使用模板,必然會(huì)牽扯到靜態(tài)文件的配置,,比如CSS,,Js等,在Django的項(xiàng)目目錄中的中追加:

STATICFILES_DIRS = (

    os.path.join(BASE_DIR,'static'),

)

其中static是存放靜態(tài)文件的目錄,,這樣就能在HTML頁面中引用特效或者圖片了,。對于模板,其實(shí)就是讀取模板,,模板中嵌套著標(biāo)簽,,然后渲染數(shù)據(jù)的時(shí)候,,從Model中取出數(shù)據(jù)插入到模板中,最后用戶接收到請求的響應(yīng),。

模板語言:

{{ item }}

{% for item in list %} <a>{{ item }}</a> {% endfor %}

{% if ordered_warranty %} {% else %} {% endif %}

父模板:{% block title %}{% endblock %}

子模板:{% extends "base.html" %}和{% block title %}{% endblock %}

其他常用方法:

{{ item.event_start|date:"Y-m-d H:i:s"}}

{{ bio|truncatewords:"30" }}

{{ my_list|first|upper }}

{{ name|lower }}

在字典中取出數(shù)據(jù)使用dict.some的形式

自定義標(biāo)簽:

因?yàn)樵谀0逭Z言中不能進(jìn)行邏輯運(yùn)算,,所以在Django中提供兩種自定義的標(biāo)簽,一種是simple_tag,,另一種是filter,。

simple_tag可以傳遞任意參數(shù),但是不能用作布爾判斷,,filter最多只能傳遞2個(gè)參數(shù),,可以用做布爾判斷,同樣的,,simple_tag和filter的實(shí)現(xiàn)是類似的,。

示例代碼:

!/usr/bin/env python

-- conding:utf-8 --

file:mycustomtags.py

from django import template

from django.utils.safestring import mark_safe

from django.template.base import resolve_variable, Node, TemplateSyntaxError

register = template.Library()

@register.simple_tag

def my_simple_time(v1,v2,v3):

return  v1 + v2 + v3

@register.simple_tag

def my_input(id,arg):

result = "<input type='text' id='%s' class='%s' />" %(id,arg,)

return mark_safe(result)

在HTML文件中導(dǎo)入之前創(chuàng)建的Python文件,使用load命令:

{% load mycustomtags %}

使用simple_tag:

{% my_simple_time 1 2 3%}

{% my_input 'id_username' 'hide'%}

需要在項(xiàng)目目錄中的中配置當(dāng)前的APP:

INSTALLED_APPS = (

'app0',  # app的名稱

)

(8)Django的中間件:

中間件示意圖:

blob.png

每一次用戶的請求都會(huì)一層一層穿過中間件,,當(dāng)不符合中間件的業(yè)務(wù)邏輯的時(shí)候就會(huì)直接返回,,用戶請求到達(dá)不了最里層的業(yè)務(wù)邏輯處理函數(shù),這樣可以自定義中間件,,在不使用Nginx等第三方工具的時(shí)候統(tǒng)計(jì)每次用戶的訪問次數(shù),。

中間件其實(shí)就是一個(gè)Python文件,但是其中的類需要繼承自from django.utils.deprecation import MiddlewareMixin,,在這個(gè)文件中可以創(chuàng)建如下5中函數(shù):

請求到來之前執(zhí)行

def process_request(self, request):

Some...

數(shù)據(jù)返回之前執(zhí)行

def process_reponse(self, request, response):

Some...

return response # 必須返回請求的數(shù)據(jù)

執(zhí)行view中的方法之前執(zhí)行

def process_view(self, request, callback, callback_args, callback_kwargs)

程序出錯(cuò)時(shí)執(zhí)行

def process_exception(self, request, exception)

渲染模板數(shù)據(jù)時(shí)執(zhí)行

def process_template_response(self, request, response)

需要在項(xiàng)目目錄中的文件中設(shè)置:

MIDDLEWARE = [

'middle.first.First',

'django.middleware.security.SecurityMiddleware',

'django.contrib.sessions.middleware.SessionMiddleware',

'django.middleware.common.CommonMiddleware',

'django.middleware.csrf.CsrfViewMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'django.contrib.messages.middleware.MessageMiddleware',

'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

(8)Django文件上傳和Form驗(yàn)證:

☆自定義文件上傳:

def uploadFile(request):

if request.method == 'POST':

   obj = request.FILES.get('xxx')

   print(obj.name) # 文件名稱

   f = open(obj,name, 'wb')

   for c in obj.chunks():

       f.write(c)

   f.close()

☆Form上傳:

def upload_file(request):

if request.method == "POST":

    obj = request.FILES.get('uploadfile')

    f = open(obj.name, 'wb')

    for chunk in obj.chunks():

        f.write(chunk)

    f.close()

return render(request, 'OK.html')

示例代碼:

HTML

<form method="post" action="/view1/" enctype="multipart/form-data">

 <input type="file" name="ExcelFile" id="id_ExcelFile" />

 <input type="submit" value="提交" />

</form>

Form

from django import forms

class FileForm(forms.Form):

ExcelFile = forms.FileField()

Models

from django.db import models

class UploadFile(models.Model):

userid = models.CharField(max_length = 30)

file = models.FileField(upload_to = './upload/')

date = models.DateTimeField(auto_now_add=True)

Views

def UploadFile(request):

uf = AssetForm.FileForm(request.POST,request.FILES)

if uf.is_valid():

        upload = models.UploadFile()

        upload.userid = 1

        upload.file = uf.cleaned_data['ExcelFile']

        upload.save()

☆A(yù)jax上傳文件:

HTML:

<div>

   {{ up.ExcelFile }}

   <input type="button" id="submitj" value="提交" />

</div>

<script src="/static/js/jquery-2.1.4.min.js"></script>

<script>

$('#submitj').bind("click",function () {

    var file = $('#id_ExcelFile')[0].files[0];

    var form = new FormData();

    form.append('ExcelFile', file);

     $.ajax({

            type:'POST',

            url: '/view1/',

            data: form,

            processData: false,  // tell jQuery not to process the data

            contentType: false,  // tell jQuery not to set contentType

            success: function(arg){

                console.log(arg);

            }

        })

})

</script>

Form:

lass FileForm(forms.Form):

ExcelFile = forms.FileField()

Models:

from django.db import models

class UploadFile(models.Model):

userid = models.CharField(max_length = 30)

file = models.FileField(upload_to = './upload/')

date = models.DateTimeField(auto_now_add=True)

Views:

from study1 import forms

def UploadFile(request):

uf = AssetForm.FileForm(request.POST,request.FILES)

if uf.is_valid():

        upload = models.UploadFile()

        upload.userid = 1

        upload.file = uf.cleaned_data['ExcelFile']

        upload.save()

        print upload.file

return render(request, 'file.html', locals())

(9)Django的Auth認(rèn)證系統(tǒng):

auth模塊是Django提供的標(biāo)準(zhǔn)權(quán)限管理系統(tǒng),,可以提供用戶的身份認(rèn)證,用戶組管理,,并且和admin模塊配合使用,。

啟用auth模塊:

Application definition

INSTALLED_APPS = [

'django.contrib.auth',

]

model:

from django.contrib.auth.models import User

數(shù)據(jù)庫中該表名為auth_user.

CREATE TABLE "auth_user" (

"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,

"password" varchar(128) NOT NULL, "last_login" datetime NULL,

"is_superuser" bool NOT NULL,

"first_name" varchar(30) NOT NULL,

"last_name" varchar(30) NOT NULL,

"email" varchar(254) NOT NULL,

"is_staff" bool NOT NULL,

"is_active" bool NOT NULL,

"date_joined" datetime NOT NULL,

"username" varchar(30) NOT NULL UNIQUE

)

新建用戶:

user = User.objects.create_user(username, email, password)

user.save()

不存儲(chǔ)用戶密碼明文而是存儲(chǔ)一個(gè)Hash值

認(rèn)證用戶:

from django.contrib.auth import authenticate

user = authenticate(username=username, password=password)

認(rèn)證用戶的密碼是否有效, 若有效則返回代表該用戶的user對象, 若無效則返回None.

該方法不檢查is_active標(biāo)識(shí)位

修改密碼:

user.set_password(new_password)

以下實(shí)例為先認(rèn)證通過后才可以修改密碼

user = auth.authenticate(username=username, password=old_password)

if user is not None:

user.set_password(new_password)

user.save()

登錄:

from django.contrib.auth import login

login向session中添加SESSION_KEY, 便于對用戶進(jìn)行跟蹤:

'login(request, user)'

login不進(jìn)行認(rèn)證,也不檢查is_active標(biāo)志位

實(shí)例:

user = authenticate(username=username, password=password)

if user is not None:

if user.is_active:

    login(request, user)

退出登錄:

logout會(huì)移除request中的user信息, 并刷新session

from django.contrib.auth import logout

def logout_view(request):

logout(request)

設(shè)置只允許登錄的用戶訪問:

@login_required裝飾器的view函數(shù)會(huì)先通過session key檢查登錄信息,已經(jīng)登錄的用戶允許正常執(zhí)行操作,,未登錄的用戶會(huì)重定向到login_url指定的位置,,這個(gè)參數(shù)在項(xiàng)目目錄中的中進(jìn)行設(shè)置。

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')

def userinfo(request):

Some...

settings 配置

LOGIN_URL = '/index/'

views

@login_required

def userinfo(request):

Some...

(11)跨站請求偽造CSRF:

Django為了用戶實(shí)現(xiàn)放置跨站請求偽造,,通過中間件django.middleware.csrf.CsrfViewMiddleware來完成,。而對于Django中設(shè)置防跨站請求偽造功能分為全局設(shè)置和局部設(shè)置。

全局使用就是直接使用django.middleware.csrf.CsrfViewMiddleware,,在項(xiàng)目目錄中的中進(jìn)行配置,。使用裝飾器可以進(jìn)行局部的設(shè)置:

@csrf_exempt取消當(dāng)前函數(shù)的防跨站請求偽造功能

@csrf_protect僅啟用當(dāng)前函數(shù)的防跨站請求偽造功能

使用時(shí)要進(jìn)行導(dǎo)入:

from django.views.decorators.csrf import csrf_exempt,csrf_protect

在Django1.10中,為了防止BREACH***,,對cookie-form類型的csrf做了一點(diǎn)改進(jìn),,即在cookie和form中的token值是不相同的。

應(yīng)用方式也分為兩種:

☆普通表單使用CSRF:

1.HTML文件中設(shè)置令牌:{% csrf_token %}

2.在View函數(shù)中設(shè)置返回值:return render(request, 'xxx.html', data)

☆A(yù)jax使用CSRF:

對于傳統(tǒng)的form,可以通過表單的方式將token再次發(fā)送到服務(wù)端,,而對于ajax的話,,使用如下方式:

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title></title>

</head>

<body>

{% csrf_token %}

<input type="button" onclick="Do();"  value="Do it"/>

<script src="/static/plugin/jquery/jquery-1.8.0.js"></script>

<script src="/static/plugin/jquery/jquery.cookie.js"></script>

<script type="text/javascript">

    var csrftoken = $.cookie('csrftoken');

    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);

            }

        }

    });

    function Do(){

        $.ajax({

            url:"/app01/test/",

            data:{id:1},

            type:'POST',

            success:function(data){

                console.log(data);

            }

        });

    }

</script>

</body>

</html>

(12)Django中的Cookie和Session:

☆獲取cookie:

request.COOKIES['key']

request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)

參數(shù):

    default: 默認(rèn)值

       salt: 加密鹽

    max_age: 后臺(tái)控制過期時(shí)間

☆設(shè)置cookie:

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

rep.set_cookie(key,value,...)

rep.set_signed_cookie(key,value,salt='加密鹽',...)

參數(shù):

key,鍵

alue='',值

max_age=None,超時(shí)時(shí)間

expires=None,超時(shí)時(shí)間(IE requires expires, so set it if hasn't been already.)

path='/', Cookie生效的路徑,/ 表示根路徑,,特殊的:跟路徑的cookie可以被任何url的頁面訪問

domain=None, Cookie生效的域名

secure=False, https傳輸

httponly=False,只能http協(xié)議傳輸,,無法被JavaScript獲取(不是絕對,,底層抓包可以獲取到也可以被覆蓋)

☆使用jQuery操作cookie:

<script src='/static/js/jquery.cookie.js'></script>

$.cookie("list_pager_num", 30,{ path: '/' });

☆Session類型:

Django默認(rèn)支持Session,,并且默認(rèn)是將Session數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫中,即:django_session 表中,。

★數(shù)據(jù)庫:

配置 :

SESSION_ENGINE = 'django.contrib.sessions.backends.db'

引擎(默認(rèn))

SESSION_COOKIE_NAME = "sessionid"

Session的cookie保存在瀏覽器上時(shí)的key,,即:sessionid=隨機(jī)字符串(默認(rèn))

SESSION_COOKIE_PATH = "/"

Session的cookie保存的路徑(默認(rèn))

SESSION_COOKIE_DOMAIN = None

Session的cookie保存的域名(默認(rèn))

SESSION_COOKIE_SECURE = False

是否Https傳輸cookie(默認(rèn))

SESSION_COOKIE_HTTPONLY = True

是否Session的cookie只支持http傳輸(默認(rèn))

SESSION_COOKIE_AGE = 1209600

Session的cookie失效日期(2周)(默認(rèn))

SESSION_EXPIRE_AT_BROWSER_CLOSE = False

是否關(guān)閉瀏覽器使得Session過期(默認(rèn))

SESSION_SAVE_EVERY_REQUEST = False

是否每次請求都保存Session,默認(rèn)修改之后才保存(默認(rèn))

def index(request):

# 獲取,、設(shè)置,、刪除Session中數(shù)據(jù)

request.session['k1']

request.session.get('k1',None)

request.session['k1'] = 123

request.session.setdefault('k1',123) # 存在則不設(shè)置

del request.session['k1']

# 所有 鍵、值,、鍵值對

request.session.keys()

request.session.values()

request.session.items()

request.session.iterkeys()

request.session.itervalues()

request.session.iteritems()

# 用戶session的隨機(jī)字符串

request.session.session_key

# 將所有Session失效日期小于當(dāng)前日期的數(shù)據(jù)刪除

request.session.clear_expired()

# 檢查 用戶session的隨機(jī)字符串 在數(shù)據(jù)庫中是否

request.session.exists("session_key")

# 刪除當(dāng)前用戶的所有Session數(shù)據(jù)

request.session.delete("session_key")

request.session.set_expiry(value)

    * 如果value是個(gè)整數(shù),,session會(huì)在些秒數(shù)后失效。

    * 如果value是個(gè)datatime或timedelta,,session就會(huì)在這個(gè)時(shí)間后失效,。

    * 如果value是0,用戶關(guān)閉瀏覽器session就會(huì)失效。

    * 如果value是None,session會(huì)依賴全局session失效策略,。

★緩存:

配置 :

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'

引擎

SESSION_CACHE_ALIAS = 'default'

使用的緩存別名(默認(rèn)內(nèi)存緩存,,也可以是memcache),此處別名依賴緩存的設(shè)置

SESSION_COOKIE_NAME = "sessionid"

Session的cookie保存在瀏覽器上時(shí)的key,,即:sessionid=隨機(jī)字符串

SESSION_COOKIE_PATH = "/"

Session的cookie保存的路徑

SESSION_COOKIE_DOMAIN = None

Session的cookie保存的域名

SESSION_COOKIE_SECURE = False

是否Https傳輸cookie

SESSION_COOKIE_HTTPONLY = True

是否Session的cookie只支持http傳輸

SESSION_COOKIE_AGE = 1209600

Session的cookie失效日期(2周)

SESSION_EXPIRE_AT_BROWSER_CLOSE = False

是否關(guān)閉瀏覽器使得Session過期

SESSION_SAVE_EVERY_REQUEST = False

是否每次請求都保存Session,,默認(rèn)修改之后才保存

★文件:

配置 :

SESSION_ENGINE = 'django.contrib.sessions.backends.file'

引擎

SESSION_FILE_PATH = None

緩存文件路徑,如果為None,,則使用tempfile模塊獲取一個(gè)臨時(shí)地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T

SESSION_COOKIE_NAME = "sessionid"

Session的cookie保存在瀏覽器上時(shí)的key,,即:sessionid=隨機(jī)字符串

SESSION_COOKIE_PATH = "/"

Session的cookie保存的路徑

SESSION_COOKIE_DOMAIN = None

Session的cookie保存的域名

SESSION_COOKIE_SECURE = False

是否Https傳輸cookie

SESSION_COOKIE_HTTPONLY = True

是否Session的cookie只支持http傳輸

SESSION_COOKIE_AGE = 1209600

Session的cookie失效日期(2周)

SESSION_EXPIRE_AT_BROWSER_CLOSE = False

是否關(guān)閉瀏覽器使得Session過期

SESSION_SAVE_EVERY_REQUEST = False

是否每次請求都保存Session,默認(rèn)修改之后才保存

★緩存+數(shù)據(jù)庫:

數(shù)據(jù)庫用于做持久化,,緩存用于提高效率,。

配置 :

SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'

引擎

★加密cookieSession:

配置 :

SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'

引擎

(13)Django的緩存:

由于Django是動(dòng)態(tài)網(wǎng)站,所有每次請求均會(huì)去數(shù)據(jù)進(jìn)行相應(yīng)的操作,,當(dāng)程序訪問量大時(shí),耗時(shí)必然會(huì)更加明顯,,最簡單解決方式是使用:緩存,,緩存將一個(gè)某個(gè)views的返回值保存至內(nèi)存或者memcache中,5分鐘內(nèi)再有人來訪問時(shí),,則不再去執(zhí)行view中的操作,,而是直接從內(nèi)存或者Redis中之前緩存的內(nèi)容拿到,,并返回。如果出現(xiàn)多個(gè)url匹配同一個(gè)view函數(shù)的情況,,緩存機(jī)制會(huì)根據(jù)每一個(gè)不同的url做單獨(dú)的緩存.Django中提供了6種緩存方式:

☆1.開發(fā)調(diào)試:

配置:

CACHES = {

   'default': {

'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 引擎

       'TIMEOUT': 300,                                              

緩存超時(shí)時(shí)間(默認(rèn)300,,None表示永不過期,0表示立即過期)

       'OPTIONS':{

          'MAX_ENTRIES': 300,                                      

最大緩存?zhèn)€數(shù)(默認(rèn)300)

          'CULL_FREQUENCY': 3,                                     

緩存到達(dá)最大個(gè)數(shù)之后,,剔除緩存?zhèn)€數(shù)的比例,,即:1/CULL_FREQUENCY(默認(rèn)3)

       },

       'KEY_PREFIX': '',                                            

緩存key的前綴(默認(rèn)空)

       'VERSION': 1,                                                 

緩存key的版本(默認(rèn)1)

       'KEY_FUNCTION' 函數(shù)名                                        

生成key的函數(shù)(默認(rèn)函數(shù)會(huì)生成為:【前綴:版本:key】)

   }

}

自定義key:

def default_key_func(key, key_prefix, version):

"""

Default function to generate keys.

Constructs the key used by all other methods. By default it prepends

the `key_prefix'. KEY_FUNCTION can be used to specify an alternate

function with custom key making behavior.

"""

return '%s:%s:%s' % (key_prefix, version, key)

def get_key_func(key_func):

"""

Function to decide which key function to use.

Defaults to ``default_key_func``.

"""

if key_func is not None:

   if callable(key_func):

       return key_func

   else:

       return import_string(key_func)

return default_key_func

☆2.內(nèi)存:

配置:

CACHES = {

       'default': {

          'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',

          'LOCATION': 'unique-snowflake',

       }

   }

☆3.文件:

配置:

CACHES = {

       'default': {

          'BACKEND': 'django.core.cache.backends.db.DatabaseCache',

          'LOCATION': 'my_cache_table', # 數(shù)據(jù)庫表

       }

   }

☆4.數(shù)據(jù)庫:

配置:

CACHES = {

       'default': {

          'BACKEND': 'django.core.cache.backends.db.DatabaseCache',

          'LOCATION': 'my_cache_table', # 數(shù)據(jù)庫表

       }

   }

執(zhí)行創(chuàng)建表命令 python manage.py createcachetable

☆5.Memcache緩存(python-memcached模塊):

配置:

CACHES = {

   'default': {

       'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',

       'LOCATION': '127.0.0.1:11211',

   }

}

CACHES = {

   'default': {

       'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',

       'LOCATION': 'unix:/tmp/memcached.sock',

   }

}  

CACHES = {

   'default': {

       'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',

       'LOCATION': [

          '172.19.26.240:11211',

          '172.19.26.242:11211',

       ]

   }

}

☆6.Memcache緩存(pylibmc模塊):

配置:

CACHES = {

   'default': {

       'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',

       'LOCATION': '127.0.0.1:11211',

   }

}

CACHES = {

   'default': {

       'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',

       'LOCATION': '/tmp/memcached.sock',

   }

}  

CACHES = {

   'default': {

       'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',

       'LOCATION': [

          '172.19.26.240:11211',

          '172.19.26.242:11211',

       ]

   }

}

☆使用緩存:

1.全站使用緩存:

MIDDLEWARE = [

    'django.middleware.cache.UpdateCacheMiddleware',

    # 其他中間件...

    'django.middleware.cache.FetchFromCacheMiddleware',

]

2.單獨(dú)視圖緩存:

2.1方式一:

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)

def my_view(request):

...

2.2方式二:

from django.views.decorators.cache import cache_page

urlpatterns = [

url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),

]

3.局部視圖使用:

引入TemplateTag:{% load cache %}

使用緩存:

{% cache 5000 緩存key %}

 緩存內(nèi)容

{% endcache %}

(14)Django信號(hào):

Django中提供了“信號(hào)調(diào)度”,用于在框架執(zhí)行操作時(shí)解耦,。通俗來講,,就是一些動(dòng)作發(fā)生的時(shí)候,信號(hào)允許特定的發(fā)送者去提醒一些接受者,。

☆內(nèi)置信號(hào):

1.Model signals

pre_init # django的modal執(zhí)行其構(gòu)造方法前,,自動(dòng)觸發(fā)

post_init # django的modal執(zhí)行其構(gòu)造方法后,自動(dòng)觸發(fā)

pre_save # django的modal對象保存前,,自動(dòng)觸發(fā)

post_save # django的modal對象保存后,,自動(dòng)觸發(fā)

pre_delete # django的modal對象刪除前,自動(dòng)觸發(fā)

post_delete # django的modal對象刪除后,,自動(dòng)觸發(fā)

m2m_changed # django的modal中使用m2m字段操作第三張表(add,remove,clear)前后,,自動(dòng)觸發(fā)

class_prepared 程序啟動(dòng)時(shí),檢測已注冊的app中modal類,,對于每一個(gè)類,,自動(dòng)觸發(fā)

2.Management signals

pre_migrate # 執(zhí)行migrate命令前,自動(dòng)觸發(fā)

post_migrate # 執(zhí)行migrate命令后,,自動(dòng)觸發(fā)

3.Request/response signals

request_started # 請求到來前,,自動(dòng)觸發(fā)

request_finished # 請求結(jié)束后,自動(dòng)觸發(fā)

got_request_exception # 請求異常后,,自動(dòng)觸發(fā)

4.Test signals

setting_changed # 使用test測試修改配置文件時(shí),,自動(dòng)觸發(fā)

template_rendered # 使用test測試渲染模板時(shí),自動(dòng)觸發(fā)

5.Database Wrappers

connection_created # 創(chuàng)建數(shù)據(jù)庫連接時(shí),,自動(dòng)觸發(fā)

使用信號(hào):

from django.core.signals import request_finished

from django.core.signals import request_started

from django.core.signals import got_request_exception

from django.db.models.signals import class_prepared

from django.db.models.signals import pre_init, post_init

from django.db.models.signals import pre_save, post_save

from django.db.models.signals import pre_delete, post_delete

from django.db.models.signals import m2m_changed

from django.db.models.signals import pre_migrate, post_migrate

from django.test.signals import setting_changed

from django.test.signals import template_rendered

from django.db.backends.signals import connection_created

定義接收到信號(hào)時(shí)執(zhí)行的回調(diào)函數(shù)

def callback(sender, **kwargs):

    print("內(nèi)置信號(hào)_callback")

    print(sender,kwargs)

注冊信號(hào)

內(nèi)置信號(hào).connect(callback)

或:

from django.core.signals import request_finished

from django.dispatch import receiver

@receiver(request_finished)

def my_callback(sender, **kwargs):

   print("Request finished!")

☆自定義信號(hào):

1.定義信號(hào):

import django.dispatch

pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

2.注冊信號(hào):

def callback(sender, **kwargs):

print("callback")

print(sender,kwargs)

pizza_done.connect(callback)

3.觸發(fā)信號(hào):

from 路徑 import pizza_done

pizza_done.send(sender='seven',toppings=123, size=456)

(16)Django中的Admin:

Django admin是一個(gè)Django提供的后臺(tái)管理頁面,,這個(gè)管理頁面提供完善的HTML和CSS,是的在model中創(chuàng)建表結(jié)構(gòu)后,,在admin中就可以增刪改查,,配置Django的Admin需要以下步驟:

1.創(chuàng)建后臺(tái)管理員

python manage.py createsuperuser

2.配置URL

url(r'^admin/', include(admin.site.urls))

3.注冊和配置Django Admin后臺(tái)管理頁面admin.py:

admin中的配置:

from django.contrib import admin

Register your models here.

admin.site.register(models.UserType)

admin.site.register(models.UserInfo)

admin.site.register(models.UserGroup)

admin.site.register(models.Asset)

設(shè)置數(shù)據(jù)表名稱:

class UserType(models.Model):

name = models.CharField(max_length=50)

class Meta:

    verbose_name = '用戶類型'

    verbose_name_plural = '用戶類型'

在model中還要:

class UserType(models.Model):

name = models.CharField(max_length=50)

def __unicode__(self):  # python3 is __str__(self)

    return self.name

為數(shù)據(jù)表添加搜索功能:

from django.contrib import admin

from app01 import models

class UserInfoAdmin(admin.ModelAdmin):

list_display = ('username', 'password', 'email')

search_fields = ('username', 'email')

admin.site.register(models.UserType)

admin.site.register(models.UserInfo,UserInfoAdmin)

admin.site.register(models.UserGroup)

admin.site.register(models.Asset)

添加快速過濾:

from django.contrib import admin

from app01 import models

class UserInfoAdmin(admin.ModelAdmin):

list_display = ('username', 'password', 'email')

search_fields = ('username', 'email')

list_filter = ('username', 'email')

admin.site.register(models.UserType)

admin.site.register(models.UserInfo,UserInfoAdmin)

admin.site.register(models.UserGroup)

admin.site.register(models.Asset)

(17)Django中的Form:

Django中的Form一般用來輸入HTML或者驗(yàn)證用戶輸入。

Form:

!/usr/bin/env python

-- coding:utf-8 --

import re

from django import forms

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('手機(jī)號(hào)碼格式錯(cuò)誤')

class PublishForm(forms.Form):

user_type_choice = (

    (0, u'普通用戶'),

    (1, u'高級(jí)用戶'),

)

user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,

                                                              attrs={'class': "form-control"}))

title = forms.CharField(max_length=20,

                        min_length=5,

                        error_messages={'required': u'標(biāo)題不能為空',

                                        'min_length': u'標(biāo)題最少為5個(gè)字符',

                                        'max_length': u'標(biāo)題最多為20個(gè)字符'},

                        widget=forms.TextInput(attrs={'class': "form-control",

                                                      'placeholder': u'標(biāo)題5-20個(gè)字符'}))

memo = forms.CharField(required=False,

                       max_length=256,

                       widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'詳細(xì)描述', 'rows': 3}))

phone = forms.CharField(validators=[mobile_validate, ],

                        error_messages={'required': u'手機(jī)不能為空'},

                        widget=forms.TextInput(attrs={'class': "form-control",

                                                      'placeholder': u'手機(jī)號(hào)碼'}))

email = forms.EmailField(required=False,

                        error_messages={'required': u'郵箱不能為空','invalid': u'郵箱格式錯(cuò)誤'},

                        widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'郵箱'}))

View:

def publish(request):

ret = {'status': False, 'data': '', 'error': '', 'summary': ''}

if request.method == 'POST':

    request_form = PublishForm(request.POST)

    if request_form.is_valid():

        request_dict = request_form.clean()

        print request_dict

        ret['status'] = True

    else:

        error_msg = request_form.errors.as_json()

        ret['error'] = json.loads(error_msg)

return HttpResponse(json.dumps(ret))

在使用Model和Form時(shí),,都需要對字段進(jìn)行定義并指定類型,,通過ModelForm則可以省去Form中字段的定義:

class AdminModelForm(forms.ModelForm):

class Meta:

    model = models.Admin

    #fields = '__all__'

    fields = ('username', 'email')

    widgets = {

        'email' : forms.PasswordInput(attrs={'class':"alex"}),

    }

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多