溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Django框架學(xué)習(xí)筆記

發(fā)布時(shí)間:2020-06-29 09:50:32 來(lái)源:網(wǎng)絡(luò) 閱讀:482 作者:cxf210210 欄目:開發(fā)技術(shù)

django框架

MVC框架

簡(jiǎn)介

MVC的產(chǎn)生理念:分工。讓專門的人去做專門的事。
MVC的核心思想:解耦
M:model模型,和數(shù)據(jù)庫(kù)進(jìn)行交互
V:view視圖,產(chǎn)生HTML頁(yè)面
C:controller控制器,接收請(qǐng)求,進(jìn)行處理,與M,V進(jìn)行交互,返回應(yīng)答

Django的MVT框架

本質(zhì)上還是MVC的思想
M:model模型,和MVC中M功能相同,和數(shù)據(jù)庫(kù)進(jìn)行交互
V:View視圖,和MVC中C功能相同,接收請(qǐng)求,進(jìn)行處理,與M和T進(jìn)行交互,返回應(yīng)答
T:template模板,和MVC中V功能相同,產(chǎn)生HTML頁(yè)面

虛擬環(huán)境

pip install virtualenv  #安裝虛擬環(huán)境
pip install virtualenvwrapper #安裝虛擬環(huán)境擴(kuò)展包
vim .bashrc  #添加以下兩行
export WORKON_HOME=$HOME/.vitualenvs
source /usr/bin/virtualenvwrapper.sh
使用source .bashrc使其生效
創(chuàng)建python3虛擬環(huán)境
mkvirtualenv -p python3 虛擬環(huán)境名
workon 虛擬環(huán)境名   #進(jìn)入虛擬環(huán)境
deactivate #退出虛擬環(huán)境

項(xiàng)目創(chuàng)建

命令:django-admin startproject myobj

項(xiàng)目下各文件說(shuō)明

init:說(shuō)明myobj是一個(gè)python包
settings.py:項(xiàng)目的配置文件
urls.py:進(jìn)行url路由的配置
wsgi.py:web服務(wù)器和Django交互的入口
manage.py:項(xiàng)目的管理文件

應(yīng)用創(chuàng)建

命令:python manage.py startapp appname

應(yīng)用下生成的文件說(shuō)明

init .py:說(shuō)明目錄是一個(gè)Python模塊
models.py:寫和數(shù)據(jù)庫(kù)項(xiàng)目的內(nèi)容
views.py:接收請(qǐng)求,進(jìn)行處理,與M和T進(jìn)行交互,返回應(yīng)答。定義處理函數(shù),視圖函數(shù)
test.py:寫測(cè)試代碼文件
admin.py:網(wǎng)站后臺(tái)管理相關(guān)的文件

建立應(yīng)用和項(xiàng)目之間的聯(lián)系,需要對(duì)應(yīng)用進(jìn)行注冊(cè)

修改settings.py的INSTALLED_APPS的內(nèi)容,添加應(yīng)用名字

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'test1',
]
運(yùn)行一個(gè)應(yīng)用
python manage.py runserver
訪問(wèn)127.0.0.1:8000可以查看創(chuàng)建的應(yīng)用

后臺(tái)管理

本地化
語(yǔ)言和時(shí)區(qū)的本地化

修改settings.py文件

LANGUAGE_CODE = 'zh-hans'  #使用中文
TIME_ZONE = 'Asia/Shanghai' #中國(guó)時(shí)區(qū)
創(chuàng)建管理員
命令:python manage.py createsuperuser
登錄后臺(tái)
瀏覽器輸入"127.0.0.1/admin"進(jìn)入后臺(tái)管理頁(yè)面
注冊(cè)模型類

在應(yīng)用下的admin.py下注冊(cè)模型類
告訴Django框架根據(jù)注冊(cè)的模型來(lái)生成對(duì)應(yīng)表管理頁(yè)面
b=Bookinfo()
str(b)

列表頁(yè)選項(xiàng)
頁(yè)大小
  • 每頁(yè)中顯示多少條數(shù)據(jù),默認(rèn)為每頁(yè)顯示100條數(shù)據(jù),屬性如下:
    list_per_page=100
    打開booktest/admin.py文件,修改AreaAdmin類如下:
    class AreaInfoAdmin(admin.ModelAdmin):
    '''地區(qū)模型管理類'''
    list_per_page=10 #指定每頁(yè)顯示10條數(shù)據(jù)
    操作選項(xiàng)的位置

    頂部顯示的屬性,設(shè)置為True在頂部顯示,設(shè)置為False不在頂部顯示,默認(rèn)為True
    actions_on_top=True
    底部顯示的屬性,設(shè)置為True在底部顯示,設(shè)置為False不在底部顯示,默認(rèn)為False
    actions_on_bottom=False

    列表中的列

    屬性如下:
    list_display=[模型字段1,模型字段2,...]
    方法列是不能排序的,如果需要排序需要為方法指定排序依據(jù)
    admin_order_field=模型類字段
    打開booktest/models.py文件,修改AreaInfo類如下:

    class AreaInfo(models.Model):
    ...
    def title(self):
        return self.atitle
    title.admin_order_field='atitle'
    列標(biāo)題

    列標(biāo)題默認(rèn)為屬性或方法的名稱,可以通過(guò)屬性設(shè)置。需要先將模型字段封裝成方法,再對(duì)方法使用這個(gè)屬性,模型字段不能直接使用這個(gè)屬性
    short_description='列標(biāo)題'
    vim booktest/models.py文件,修改AreaInfo類如下:

    class AreaInfo(models.Model):
    ...
    title.short_description='區(qū)域名稱'
    右側(cè)欄過(guò)濾器

    屬性如下,只能接收字段,會(huì)將對(duì)應(yīng)字段的值列出來(lái),用于快速過(guò)濾。一般用于有重復(fù)值的字段。
    list_filter=[]

    搜索框

    屬性如下,用于對(duì)指定字段的值進(jìn)行搜索,支持模糊查詢。列表類型,表示在這些字段上進(jìn)行搜索。
    search_fields=[]

    編輯頁(yè)選項(xiàng)
    顯示字段順序

    屬性如下:
    fields=[]
    vim booktest/admin.py

    class AreaAdmin(admin.ModelAdmin):
    ...
    fields=['aprent','atitle']
    分組顯示

    屬性如下:

    fieldset=(
    ('組1標(biāo)題',{'fields':('字段1','字段2')}),
    ('組2標(biāo)題',{'fields':('字段3','字段4')}),
    )

    vim booktest/admin.py文件,修改AreaAdmin類如下:

    class AreaAdmin(admin.ModelAdmin):
    ...
    #fields=['aparent','atitle']
    fieldsets=(
        ('基本',{'fields':['atitle']}),
        ('高級(jí)',{'fields':['aparent']})
    )
    關(guān)聯(lián)對(duì)象

    在一對(duì)多的關(guān)系中,可以在一端的編輯頁(yè)面中編輯多端的對(duì)象,嵌入多端對(duì)象的方式包括表格、塊兩種。類型InlineModelAdmin:表示在模型的編輯頁(yè)面嵌入關(guān)聯(lián)模型的編輯。子類Tabularlnline:以表格的形式嵌入。子類StackedInline:以塊的形式嵌入。
    打開booktest/admin.py文件,創(chuàng)建AreaStackedInline類。

    class AreaStackedInline(admin.StackedInline):
    model=AreaInfo #關(guān)聯(lián)子對(duì)象
    extra=2 #額外編輯2個(gè)子對(duì)象

    打開booktest/admin.py文件,修改AreaAdmin類如下:

    class AreaAdmin(admin.ModelAdmin):
    ...
    inlines=[AreaStackedInline]

orm框架

Object:對(duì)象-類
Mapping:映射,建立類與表的對(duì)應(yīng)關(guān)系
Relation:關(guān)系,關(guān)系數(shù)據(jù)庫(kù)中的表
Django中內(nèi)嵌了orm框架,orm框架可以通過(guò)類和對(duì)象操作對(duì)應(yīng)的數(shù)據(jù)表,不需要寫sql語(yǔ)句

django orm框架的功能
  1. 建立模型和表之間的對(duì)應(yīng)關(guān)系,允許我們通過(guò)面向?qū)ο蟮姆绞絹?lái)操作數(shù)據(jù)庫(kù)
  2. 根據(jù)設(shè)計(jì)的模型類生成數(shù)據(jù)庫(kù)中的表格。
  3. 通過(guò)方便的配置就可以進(jìn)行數(shù)據(jù)庫(kù)的切換
設(shè)計(jì)類:模型類

創(chuàng)建模型類

#圖書類
class BookInfo(models.Model):
    '''圖書模型類'''
    #圖書名稱,Charfield說(shuō)明是一個(gè)字符串,max_length指定字符串的最大長(zhǎng)度
    btitle=models.CharField(max_length=20)
    #出版日期,DateField說(shuō)明是一個(gè)日期類型
    bpub_date=models.DateField()

orm另外一個(gè)作用:根據(jù)設(shè)計(jì)的類生成數(shù)據(jù)庫(kù)中的表

模型類生成表

  1. 生成遷移文件
    命令:python manage.py makemigrations
    遷移文件是根據(jù)模型類生成的
  2. 執(zhí)行遷移生成表
    命令:python manage.py migrate

通過(guò)模型類操作數(shù)據(jù)表

往表中添加數(shù)據(jù)
python manage.py shell

>>> from test1.models import BookInfo
>>> b=BookInfo()
>>> b.btitle='天龍八部'
>>> from datetime import date
>>> b.bpub_date=date(1990,1,1)
>>> b.save()
>>> BookInfo.objects.get(id=1)
<BookInfo: BookInfo object (1)>
>>> b2=BookInfo.objects.get(id=1)
>>> b2.btitle
'天龍八部'
>>> b2.bpub_date
datetime.date(1990, 1, 1)
>>> b2.id
1
>>> b2.bpub_date=date(2019,1,1)
>>> b2.save()
>>> b3=BookInfo.objects.get(id=1)
>>> b3.bpub_date
datetime.date(2019, 1, 1)
>>> b2.delete()
(1, {'test1.BookInfo': 1})

模型類關(guān)系和模型查詢

vim models.py

class HeroInfo(models.Model):
     hname =models.CharField(max_length=20)  #英雄名稱
     #性別,Booleanfield說(shuō)明是bool類型,default指定默認(rèn)值,F(xiàn)alse代表男
     hgender=models.BooleanField(default=False)
     #備注
     hcomment=models.CharField(max_length=128)
     #關(guān)系屬性 hbook,建立圖書類和英雄人物類之間的一對(duì)多關(guān)系
     #關(guān)系屬性對(duì)應(yīng)的表的字段名格式:關(guān)系屬性名_id
     hbook=models.ForeignKey('BookInfo',on_delete=models.CASCADE,)

生成遷移文件
python3 manage.py makemigrations
執(zhí)行遷移文件生成表
python3 manage.py migrate
往表中操作數(shù)據(jù)
python manage.py shell

from test1.models import BookInfo,HeroInfo
b=BookInfo()
b.btitle='天龍八部'
from datetime import date
b.bpub_date=date(1990,1,1)
b.save()
h=HeroInfo()
h.hname='段譽(yù)'
h.hgender=False
h.hcomment='六脈神劍'
h.hbook=b
h.save()
h3=HeroInfo()
h3.hname='喬峰'
h3.hcomment='降龍十八掌'
h3.hbook=b
h3.save()
h4=HeroInfo.objects.get(id=2)
h4.hname
'喬峰'
h4.hgender
False
h4.hcomment
'降龍十八掌'
h4.hbook_id
3
h4.hbook.btitle
'天龍八部'
模型類屬性命名限制
  1. 不能是python保留的關(guān)鍵字
  2. 不允許使用連續(xù)的下劃線,這是由Django的查詢方式?jīng)Q定的
  3. 定義屬性時(shí)需要指定字段類型,通過(guò)字段類型的參數(shù)指定選項(xiàng),語(yǔ)法如下:
    屬性名=models.字段類型(選項(xiàng))
    字段類型

    使用時(shí)需要引入django.db.models包,字段類型如下:

類型 描述
AutoField 自動(dòng)增長(zhǎng)的integerfield,通常不用指定,不指定是Django會(huì)自動(dòng)創(chuàng)建屬性名為id的自動(dòng)增長(zhǎng)屬性
BooleanField 布爾字段,值為True或False
NullBooleanField 支持Null、True、False三種值
CharField(max_length=最大長(zhǎng)度) 字符串,參數(shù)max_length表示最大字符個(gè)數(shù)
TextField 大文本字段,一般超過(guò)4000個(gè)
IntegerField 整數(shù)
DecimalField(max_digits=None,decimal_place=None) 十進(jìn)制浮點(diǎn)數(shù)。參數(shù)max_digits表示總位。參數(shù)decimal_places表示小數(shù)位數(shù)
FloatField 浮點(diǎn)數(shù)。參數(shù)同上
DateField:([auto_now=False,auto_now_add=False]) 日期。1.參數(shù)auto_now表示每次保存對(duì)象時(shí),自動(dòng)設(shè)置該字段為當(dāng)前時(shí)間,用于“最后一次修改”的時(shí)間戳,他總是使用當(dāng)前日期,默認(rèn)為false。2.參數(shù)auto_now_add表示當(dāng)對(duì)象第一次被創(chuàng)建時(shí)自動(dòng)設(shè)置當(dāng)前時(shí)間,用于創(chuàng)建的時(shí)間戳,他總是使用當(dāng)前日期,默認(rèn)為false。3.參數(shù)auto_now_add 和auto_now是相互排斥的,組合將會(huì)發(fā)生錯(cuò)誤。
TimeField 時(shí)間,參數(shù)同datefield
DateTimeField 日期時(shí)間,參數(shù)同DateField
FileField 上傳文件字段
ImageField 繼承于FileField,對(duì)上傳的內(nèi)容進(jìn)行校驗(yàn),確保是有效的圖片
選項(xiàng)

通過(guò)選項(xiàng)實(shí)現(xiàn)對(duì)字段的約束,選項(xiàng)如下:

選項(xiàng)名 描述
default 默認(rèn)值,設(shè)置默認(rèn)值
primary_key 若為True,則該字段會(huì)成為模型的主鍵字段,默認(rèn)值為false,一般作為autofield的選項(xiàng)使用
unique 如果為True,這個(gè)字段在表中必須唯一值,默認(rèn)值是false
db_index 若值為True,則在表中會(huì)為此字段創(chuàng)建索引,默認(rèn)值是false
db_column 字段的名稱,如果未指定,則使用屬性的名稱
null 如果為True,表示允許為空,默認(rèn)值是false
blank 如果為True,則該字段允許為空白,默認(rèn)值是false

MVT綜合案例

vim test1/urls.py

urlpatterns =[
    #通過(guò)url函數(shù)設(shè)置url路由配置項(xiàng)
    url(r'^index$',views.index), # 建立index和視圖之間的關(guān)系
    url(r'^index2$',views.index2),
    url(r'^books$',views.show_books), #顯示圖書信息
    url(r'^books/(\d+)$',views.detail), #顯示英雄信息
]

vim views.py

def show_books(request):
    '''顯示圖書的信息'''
    #1.通過(guò)M查找圖書表中的數(shù)據(jù)
    books=BookInfo.objects.all()
    #2.使用模板
    return render(request,'test1/show_books.html',{'books':books})
def detail(request,bid):
    '''查詢圖書關(guān)聯(lián)英雄信息'''
    #1.根據(jù)bid查詢圖書信息
    book=BookInfo.objects.get(id=bid)
    #2.查詢和book關(guān)聯(lián)的英雄信息
    heros=book.heroinfo_set.all()
    #3.使用模板
    return render(request,'test1/detail.html',{'book':book,'heros':heros})

vim templates/test1/show_books.html


<!DOCTYPE>
<html lang="en">
<head>
        <meta charset="UTF-8">
        <title>顯示圖書信息</title>
</head>
<body>
圖書信息如下:
<ul>
        {% for book in books %}
                <li><a href="/books/{{ book.id }}">{{ book.btitle }}</a></li>
        {% endfor %}
</ul>
</body>
</html>

vim detail.html

<!DOCTYPE html>
<html lang="en">
<head>
        <meta charset="UTF-8">
        <title>顯示圖書關(guān)聯(lián)的英雄信息</title>
</head>
<body>
<h2>{{ book.btitle }}</h2>
英雄信息如下:<br/>
<ul>
        {% for hero in heros  %}
                <li>{{ hero.hname }}--{{ hero.hcomment }}</li>
        {% empty %}
                <li>沒(méi)有英雄信息</li>
        {% endfor %}
</ul>
</body>
</html>

配置使用mysql數(shù)據(jù)庫(kù)

vim settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'booktest',   #注冊(cè)應(yīng)用
]
DATABASES = {
    'default': {
        #'ENGINE': 'django.db.backends.sqlite3',
        #'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'booktest', #使用的數(shù)據(jù)庫(kù)名字
        'USER': 'root',  #mysql用戶名
        'PASSWORD': 'root', #mysql密碼
        'HOST': 'localhost', #mysql主機(jī)
        'PORT': 3306,
    }
}

創(chuàng)建數(shù)據(jù)庫(kù)

create database booktest charset=utf8;

安裝pymysql

pip install pymysql

vim __init__.py

ALLOWED_HOSTS = ['60.205.177.168']

后臺(tái)管理

  1. 本地化
    • 語(yǔ)言和時(shí)區(qū)的本地化,修改settings.py文件
  2. 創(chuàng)建管理員
    • 命令:Python manage.py createsuperuser
  3. 注冊(cè)模型類
    • 在應(yīng)用下的admin.py中注冊(cè)模型類
    • 告訴Django框架根據(jù)注冊(cè)的模型類來(lái)生成對(duì)應(yīng)表管理頁(yè)面
      from test1.models import BookInfo
      # Register your models here.
      #注冊(cè)模型類
      admin.site.register(BookInfo)

      vim models.py

      class BookInfo(models.Model):
      '''圖書模型類'''
      btitle=models.CharField(max_length=20)
      #出版日期,DateField說(shuō)明是一個(gè)日期類型
      bpub_date=models.DateField()
      def __str__(self):
      #返回書名
      return self.btitle
  4. 自定義管理頁(yè)面
    自定義模型管理類。模型管理類就是告訴Django在生成的管理頁(yè)面上顯示哪些內(nèi)容
class BookInfoAdmin(admin.ModelAdmin):
    '''圖書模型管理類'''
    list_display=['id','btitle','bpub_date']

class HeroInfoAdmin(admin.ModelAdmin):
    '''英雄模型人物類'''
    list_display=['id','hname','hcomment']

#注冊(cè)模型類
admin.site.register(BookInfo,BookInfoAdmin)
admin.site.register(HeroInfo,HeroInfoAdmin)

視圖

在Django中,通過(guò)瀏覽器去請(qǐng)求一個(gè)頁(yè)面時(shí),使用視圖函數(shù)來(lái)處理這個(gè)請(qǐng)求的,視圖函數(shù)處理之后,要給瀏覽器返回頁(yè)面內(nèi)容
返回HTML內(nèi)容httpresponse,也可能重定向redirect

視圖函數(shù)的使用

定義視圖函數(shù)

視圖函數(shù)定義在views.py中
視圖函數(shù)必須有一個(gè)參數(shù)request,是一個(gè)httprequest類型的對(duì)象,參數(shù)名可以變化,進(jìn)行處理之后,需要返回一個(gè)HttpResponse的類對(duì)象,hello,python就是返回給瀏覽器顯示的內(nèi)容
例:

from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
#1.定義視圖函數(shù),HttpRequest
#2.進(jìn)行url配置,建立url地址和視圖的對(duì)應(yīng)關(guān)系
#http://127.0.0.1:8000/index
def index(request):
    #進(jìn)行處理,和M,T進(jìn)行交互
    return HttpResponse('老鐵沒(méi)毛病')
def index2(request):
    return HttpResponse('hello python')
進(jìn)行url配置
  • 所有的url配置項(xiàng)都定義在一個(gè)叫做urlpatterns的列表中,每一個(gè)元素都是一個(gè)配置項(xiàng)
  • 每一個(gè)配置項(xiàng)都會(huì)調(diào)用url函數(shù),第一個(gè)參數(shù)是正則表達(dá)式,第二個(gè)參數(shù)是對(duì)應(yīng)的處理動(dòng)作,可以寫一個(gè)視圖函數(shù)的名字
  • 和url字符串進(jìn)行正則匹配,匹配成功則執(zhí)行其后對(duì)應(yīng)的處理動(dòng)作
  • 對(duì)應(yīng)的動(dòng)作可以是一個(gè)視圖函數(shù)的名字,也可以是包含一個(gè)應(yīng)用的urls.py文件

url配置的目的是建立url和視圖函數(shù)的對(duì)應(yīng)關(guān)系。url配置項(xiàng)定義在urlpatterns的列表中,每一個(gè)配置項(xiàng)都調(diào)用url函數(shù)。
url函數(shù)有兩個(gè)參數(shù),第一個(gè)參數(shù)是一個(gè)正則表達(dá)式,第二個(gè)是對(duì)應(yīng)的處理動(dòng)作。
配置url時(shí),有兩種語(yǔ)法格式:

  • url(正則表達(dá)式,視圖函數(shù)名)
  • url(正則表達(dá)式,include(應(yīng)用中的urls文件))
    工作中在配置url時(shí),首先在項(xiàng)目的urls.py文件中添加配置項(xiàng)時(shí),并不寫具體的url和視圖函數(shù)之間的對(duì)應(yīng)關(guān)系,而是包含具體應(yīng)用的urls.py文件,在應(yīng)用的urls.py文件中寫url和視圖函數(shù)的對(duì)應(yīng)關(guān)系。

    url匹配的過(guò)程

    在項(xiàng)目的urls.py文件中包含具體應(yīng)用的urls.py文件,應(yīng)用的urls.py文件中寫url和視圖函數(shù)的對(duì)應(yīng)關(guān)系
    當(dāng)用戶輸入如127.0.0.1:8000/index時(shí),去除域名和最前面的/,剩下index,拿index字符串到項(xiàng)目的urls文件中進(jìn)行匹配,配置成功之后,繼續(xù)到項(xiàng)目中的urls文件中進(jìn)行正則匹配,匹配成功之后執(zhí)行視圖函數(shù)index,index視圖函數(shù)返回內(nèi)容hello python 給瀏覽器來(lái)顯示
    vim /myobj/urls.py

    from django.contrib import admin
    #from django.urls import path
    from django.conf.urls import include,url
    urlpatterns = [
    url(r'^admin/',admin.site.urls),#配置項(xiàng)
    url(r'^',include('test1.urls')) #包含test1應(yīng)用中的urls文件
    ]

    vim test1/urls.py

    from django.conf.urls import url
    from test1 import views
    # /index
    #在應(yīng)用的urls文件中進(jìn)行url配置的時(shí)候:
    #1.嚴(yán)格匹配開頭和結(jié)尾
    urlpatterns =[
    #通過(guò)url函數(shù)設(shè)置url路由配置項(xiàng)
    url(r'^index$',views.index), # 建立index和視圖之間的關(guān)系
    url(r'^index2$',views.index2),
    ]

    錯(cuò)誤視圖

    404:找不到頁(yè)面,關(guān)閉調(diào)試模式之后,默認(rèn)會(huì)顯示一個(gè)標(biāo)準(zhǔn)的錯(cuò)誤頁(yè)面,如果要顯示自定義的頁(yè)面,則需要templates目錄下面自定義一個(gè)404.html文件

    • url沒(méi)有配置
    • url配置錯(cuò)誤
      500:服務(wù)器端的錯(cuò)誤
    • 視圖出錯(cuò)
      網(wǎng)站開發(fā)完成需要關(guān)閉調(diào)試模式,在settings.py文件中:
    • DEBUG=False
    • ALLOWED_HOST=['*']

捕獲url參數(shù)

進(jìn)行url匹配時(shí),把所需要的捕獲的部分設(shè)置成一個(gè)正則表達(dá)式組,這樣Django框架就會(huì)自動(dòng)把匹配成功后相應(yīng)組的內(nèi)容作為參數(shù)傳遞給視圖函數(shù)。

  1. 位置參數(shù)
    • 位置參數(shù),參數(shù)名可以隨意指定
      vim booktest/urls.py
      from django.conf.urls import url
      from booktest import views
      urlpatterns = [
      url(r'^index$',views.index), #首頁(yè),
      url(r'^showarg(\d+)$',views.show_arg), #捕獲url參數(shù)
      ]

      vim test3/urls.py

      urlpatterns = [
      path('admin/', admin.site.urls),
      url(r'^',include('booktest.urls')),
      ]

      vim booktest/views.py

      from django.shortcuts import render
      from django.http import HttpResponse
      # Create your views here.
      def index(request):
      '''首頁(yè)'''
      return render(request,'booktest/index.html')
      def show_arg(request,num):
      return HttpResponse(num)
  2. 關(guān)鍵字參數(shù):在位置參數(shù)的基礎(chǔ)上給正則表達(dá)式組命名即可
    • ?P<組名>
    • 關(guān)鍵字參數(shù),視圖中參數(shù)名必須和正則表達(dá)式組名一致
      vim booktest.urls
      from django.conf.urls import url
      from booktest import views
      urlpatterns = [
      url(r'^index$',views.index), #首頁(yè),
      url(r'^showarg(\d+)$',views.show_arg), #捕獲url參數(shù):位置參數(shù)
      url(r'^showarg(?P<num>\d+)$',views.show_arg), #捕獲關(guān)鍵字參數(shù)
      ]

登錄案例

  1. 顯示出登錄頁(yè)面
    • 設(shè)計(jì)url,通過(guò)瀏覽器訪問(wèn)http://127.0.0.1:8000/login時(shí)顯示登錄頁(yè)面
    • 設(shè)計(jì)url對(duì)應(yīng)的視圖函數(shù)login
    • 編寫模板文件login.htnl
      vim booktest/urls.py
      from django.conf.urls import url
      from booktest import views
      urlpatterns = [
      url(r'^index$',views.index), #首頁(yè),
      url(r'^showarg(\d+)$',views.show_arg), #捕獲url參數(shù):位置參數(shù)
      url(r'^showarg(?P<num>\d+)$',views.show_arg), #捕獲關(guān)鍵字參數(shù)
      url(r'^login$',views.login), #顯示登錄頁(yè)面
      url(r'^login_check$',views.login_check),
      ]

      vim login.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
      <meta charset="UTF-8">
      <title>登錄頁(yè)面</title>
      </head>
      <body>
      <form method="post" action="/login_check">
      用戶名:<input type="text" name="username"><br/>
      密碼:<input type="password" name="password"><br/>
      <input type="submit" value="登錄">
      </form>
      </body>
      </html>
url 視圖 模板文件
/login login login.html
  1. 登錄校驗(yàn)功能
    • 設(shè)計(jì)url,點(diǎn)擊登錄頁(yè)的登錄按鈕發(fā)起請(qǐng)求http://127.0.0.1:8000/login_check
    • 設(shè)計(jì)url對(duì)應(yīng)的視圖函數(shù)login_check。接收表單提交過(guò)來(lái)的數(shù)據(jù)

注釋掉settings.py文件的47行

vim booktest/views.py

from django.shortcuts import render,redirect
from django.http import HttpResponse
# Create your views here.
def index(request):
    '''首頁(yè)'''
    return render(request,'booktest/index.html')
def show_arg(request,num):
    return HttpResponse(num)

def login(request):
    '''顯示登錄頁(yè)面'''
    return render(request,'booktest/login.html')

def login_check(request):
    '''登錄校驗(yàn)視圖'''
    #request.POST保存的是post方式提交的參數(shù) QueryDict
    # request.GET保存的是get方式提交的參數(shù)
    #1. 獲取提交的用戶名和密碼
    username=request.POST.get('username')
    password=request.POST.get('password')
    #2. 進(jìn)行登錄的校驗(yàn)
    #實(shí)際開發(fā):根據(jù)用戶和密碼查找數(shù)據(jù)庫(kù)
    #模擬:smart 123
    if username=='smart' and password=='123':
        #用戶名密碼正確,跳轉(zhuǎn)到首頁(yè)
        return redirect('/index')
    else:
        #用戶名或密碼錯(cuò)誤,跳轉(zhuǎn)到登錄頁(yè)面
        return redirect('/login')

HttpRequest對(duì)象的屬性

  • path:一個(gè)字符串,表示請(qǐng)求的頁(yè)面的完整路徑,不包含域名和參數(shù)部分
  • method:一個(gè)字符串,表示請(qǐng)求使用的HTTP方法,常用值包括:'GET'、'POST'
    • 在瀏覽器中給出地址發(fā)出請(qǐng)求采用get方式,如超鏈接
    • 在瀏覽器中點(diǎn)擊表單的提交按鈕發(fā)起請(qǐng)求,如果表單的method設(shè)置為post則為post請(qǐng)求
  • encoding:一個(gè)字符串,表示提交的數(shù)據(jù)的編碼方式
    • 如果為none則表示使用瀏覽器的默認(rèn)設(shè)置,一般為utf-8
    • 這個(gè)屬性是可寫的,可以通過(guò)修改他來(lái)修改訪問(wèn)表單數(shù)據(jù)使用的編碼,接下來(lái)對(duì)屬性的任何訪問(wèn)將使用新的encoding值
  • GET:QueryDict類型對(duì)象,類似于字典,包含get請(qǐng)求方式的所有參數(shù)
  • POST:QueryDict類型對(duì)象,類似于字典,包含post請(qǐng)求方式的所有參數(shù)
  • FILES:一個(gè)類似于字典的對(duì)象,包含所有的上傳文件
  • COOKIES:一個(gè)標(biāo)準(zhǔn)的python字典,包含所有的cookie,鍵和值都為字符串
  • session:一個(gè)既可讀又可寫的類似于字典的對(duì)象,表示當(dāng)前的對(duì)話,只有當(dāng)Django啟用會(huì)話的支持時(shí)才可用,詳細(xì)內(nèi)容見“狀態(tài)保持”
  • 運(yùn)行服務(wù)器,在瀏覽器中瀏覽首頁(yè),可以在瀏覽器“開發(fā)者工具”中看到請(qǐng)求信息如下圖

Ajax登錄案例

  • 首先分析出請(qǐng)求地址時(shí)需要攜帶的參數(shù)
  • 視圖函數(shù)處理完成之后,所返回的json格式
    1. 顯示出登錄頁(yè)面
      • 設(shè)計(jì)url,通過(guò)瀏覽器訪問(wèn)http://127.0.0.1:8000/login_ajax時(shí)顯示登錄頁(yè)面
      • 設(shè)計(jì)url對(duì)應(yīng)的視圖函數(shù)login_ajax
      • 編寫模板文件login_ajax.html。在里面寫jQuery代碼發(fā)起ajax請(qǐng)求
    2. 登錄校驗(yàn)功能
      • 設(shè)計(jì)url,點(diǎn)擊登錄頁(yè)的登錄按鈕發(fā)起請(qǐng)求,http://127.0.0.1:8000/login_ajax_check時(shí)進(jìn)行登陸校驗(yàn)
      • 設(shè)計(jì)url對(duì)應(yīng)的視圖函數(shù)login_ajax_check,接收一個(gè)提交過(guò)來(lái)的數(shù)據(jù)

狀態(tài)保持

cookie

cookie是由服務(wù)器生成,存儲(chǔ)在瀏覽器端的一小段文本信息

cookie的特點(diǎn)
  1. 以鍵值對(duì)方式進(jìn)行存儲(chǔ)
  2. 通過(guò)瀏覽器訪問(wèn)同一個(gè)網(wǎng)站時(shí),會(huì)將瀏覽器存儲(chǔ)的跟網(wǎng)站相關(guān)的所有cookie信息發(fā)送給該網(wǎng)站的服務(wù)器。request.COOKIES
  3. cookie是基于域名安全的
  4. cookie是有過(guò)期時(shí)間的,如果不指定,默認(rèn)關(guān)閉瀏覽器之后cookie就會(huì)過(guò)期
cookie請(qǐng)求的步驟
  1. 服務(wù)端接收瀏覽器發(fā)送來(lái)的請(qǐng)求并進(jìn)行處理
  2. 設(shè)置cookie,需要一個(gè)HTTPresponse類的對(duì)象,或者是它子類的對(duì)象,將cookie發(fā)送給瀏覽器保存
  3. 瀏覽器將cookie發(fā)送給服務(wù)器,保存request對(duì)象的COOKIES

vim booktest/urls.py

from django.shortcuts import render,redirect
from django.http import HttpResponse
from datetime import datetime,timedelta
# /set_cookie
def set_cookie(request):
    '''設(shè)置一個(gè)cookie信息'''
    response=HttpResponse('設(shè)置cookie')
    # 設(shè)置一個(gè)cookie信息,名字為num,值為1
    response.set_cookie('num',1,max_age=14*24*3600)
    #response.set_cookie('num', 1, expires=datetime.now()+timedelta(days=14))
    #返回response
    return response

# /get_cookie
def get_cookie(request):
    '''獲取cookie的信息'''
    #取出cookie num的值
    num=request.COOKIES['num']
    return HttpResponse(num)

vim booktest/urls.py

urlpatterns = [
    url(r'^index$',views.index), #首頁(yè),
    url(r'^showarg(\d+)$',views.show_arg), #捕獲url參數(shù):位置參數(shù)
    url(r'^showarg(?P<num>\d+)$',views.show_arg), #捕獲關(guān)鍵字參數(shù)
    url(r'^login$',views.login), #顯示登錄頁(yè)面
    url(r'^login_check$',views.login_check),
    url(r'^set_cookie$',views.set_cookie), #設(shè)置cookie
    url(r'^get_cookie$',views.get_cookie),  #獲取cookie
]
記住用戶名的案例

vim login.html

<form method="post" action="/login_check">
    用戶名:<input type="text" name="username" value="{{ username }}"><br/>
    密碼:<input type="password" name="password"><br/>
    <input type="checkbox" name="remember">記住用戶名<br/>
    <input type="submit" value="登錄">
</form>

vim booktest/views.py

def login(request):
    '''顯示登錄頁(yè)面'''
    #獲取cookie username
    if 'username' in request.COOKIES:
        #獲取記住的用戶名
        username = request.COOKIES['username']
    else:
        username=''
    return render(request,'booktest/login.html',{'username':username})

def login_check(request):
    '''登錄校驗(yàn)視圖'''
    #request.POST保存的是post方式提交的參數(shù) QueryDict
    # request.GET保存的是get方式提交的參數(shù)
    #1. 獲取提交的用戶名和密碼
    username=request.POST.get('username')
    password=request.POST.get('password')
    remember=request.POST.get('remember')
    #2. 進(jìn)行登錄的校驗(yàn)
    #實(shí)際開發(fā):根據(jù)用戶和密碼查找數(shù)據(jù)庫(kù)
    #模擬:smart 123
    if username=='smart' and password=='123':
        #用戶名密碼正確,跳轉(zhuǎn)到首頁(yè)
        response=redirect('/index')
        #判斷是否需要記住用戶名
        if remember == 'on':
            #設(shè)置cookie username,過(guò)期時(shí)間為一周
            response.set_cookie('username',username,max_age=7*24*3600)
        return response
    else:
        #用戶名或密碼錯(cuò)誤,跳轉(zhuǎn)到登錄頁(yè)面
        return redirect('/login')
session

session存儲(chǔ)在服務(wù)器端

session的特點(diǎn)
  1. session是以鍵值對(duì)進(jìn)行存儲(chǔ)的
  2. session依賴于cookie。唯一的標(biāo)識(shí)碼保存在sessionid cookie中
  3. session也是有過(guò)期時(shí)間,如果不指定,默認(rèn)兩周就會(huì)過(guò)期
設(shè)置session

vim booktest/views.py

#/set_session
def set_session(request):
    '''設(shè)置session'''
    request.session['username']='smart'
    request.session['age']=18
    return HttpResponse('設(shè)置session')

#/get_session
def get_session(request):
    '''獲取session'''
    username=request.session['username']
    age=request.session['age']
    return HttpResponse(username+':'+str(age))
#/clear_session
def clear_session(request):
    '''清除session信息'''
    #request.session.clear()
    request.session.flush()
    #del request.session['age']
    return HttpResponse('清除成功')    

vim booktest/urls.py

url(r'^set_session$',views.set_session), #設(shè)置session
url(r'^get_session$',views.get_session), #獲取session
url(r'^clear_session$',views.clear_session), #清除session
設(shè)置會(huì)話的超時(shí)時(shí)間

如果沒(méi)有指定過(guò)期時(shí)間則兩個(gè)星期后過(guò)期
request.sesion.set_expiry(value)

  • 如果value是一個(gè)整數(shù),會(huì)話的session_id cookie將在value秒沒(méi)有活動(dòng)后過(guò)期
  • 如果value為0,那么用戶會(huì)話的session_id cookie將在用戶的瀏覽器關(guān)閉時(shí)過(guò)期
  • 如果value為None,那么會(huì)話的session_id cookie兩周之后過(guò)期
記住用戶登錄狀態(tài)案例

vim views.py

def login(request):
    '''顯示登錄頁(yè)面'''
    #判斷用戶是否登錄
    if request.session.has_key('islogin'):
        return redirect('/index')
    else:
        #用戶未登錄
        #獲取cookie username
        if 'username' in request.COOKIES:
            #獲取記住的用戶名
            username = request.COOKIES['username']
        else:
            username=''
        return render(request,'booktest/login.html',{'username':username})

def login_check(request):
    '''登錄校驗(yàn)視圖'''
    #request.POST保存的是post方式提交的參數(shù) QueryDict
    # request.GET保存的是get方式提交的參數(shù)
    #1. 獲取提交的用戶名和密碼
    username=request.POST.get('username')
    password=request.POST.get('password')
    remember=request.POST.get('remember')
    #2. 進(jìn)行登錄的校驗(yàn)
    #實(shí)際開發(fā):根據(jù)用戶和密碼查找數(shù)據(jù)庫(kù)
    #模擬:smart 123
    if username=='smart' and password=='123':
        #用戶名密碼正確,跳轉(zhuǎn)到首頁(yè)
        response=redirect('/index')
        #判斷是否需要記住用戶名
        if remember == 'on':
            #設(shè)置cookie username,過(guò)期時(shí)間為一周
            response.set_cookie('username',username,max_age=7*24*3600)
        #記住用戶登錄狀態(tài)
        #只有session中有islogin,就認(rèn)為用戶已登錄
        request.session['islogin']=True
        return response
    else:
        #用戶名或密碼錯(cuò)誤,跳轉(zhuǎn)到登錄頁(yè)面
        return redirect('/login')
cookie和session的應(yīng)用場(chǎng)景
  • cookie:記住用戶名,安全性要求不高
  • session:涉及到安全性要求比較高的數(shù)據(jù)

模板

模板的功能

  • 產(chǎn)生html,控制頁(yè)面上展示的內(nèi)容。模板文件不僅僅是一個(gè)html文件。模板文件包含兩部分內(nèi)容:
    1. 靜態(tài)內(nèi)容:css,js,html
    2. 動(dòng)態(tài)內(nèi)容:用于動(dòng)態(tài)去產(chǎn)生一些網(wǎng)頁(yè)內(nèi)容。通過(guò)模板語(yǔ)言來(lái)產(chǎn)生

模板文件的使用

通常是在視圖函數(shù)中使用模板產(chǎn)生html內(nèi)容返回給客戶端

  1. 創(chuàng)建模板文件夾
    在項(xiàng)目目錄下創(chuàng)建一個(gè)文件夾
  2. 配置模板目錄
    vim settings.py
    'DIRS': [os.path.join(BASE_DIR,'templates')],
  3. 使用模板文件
    • 加載模板文件loader.get_template
      去模板目錄下面獲取HTML文件的內(nèi)容,得到一個(gè)模板對(duì)象
    • 定義模板上下文RequeseContext
      向模板文件傳遞數(shù)據(jù)
    • 模板渲染產(chǎn)生html頁(yè)面內(nèi)容render
      用傳遞的數(shù)據(jù)替換相應(yīng)的變量,得到一個(gè)替換后的標(biāo)準(zhǔn)的HTML內(nèi)容

模板文件加載順序

django.template.loaders.filesystem.Loader:/root/wanger/test4/templates/booktest/index2.html(來(lái)源不存在)
django.template.loaders.app_directories.Loader:/root/.virtualenvs/wanger/lib/python3.5/site-packages/django/contrib/admin/templates/booktest/index2.html(來(lái)源不存在)
django.template.loaders.app_directories.Loader:/root/.virtualenvs/wanger/lib/python3.5/site-packages/django/contrib/auth/templates/booktest/index2.html(來(lái)源不存在)
  • 首先去配置的模板目錄下面去找模板文件
  • 去INSYALL_APPS下面的每個(gè)應(yīng)用的去找模板文件,前提是應(yīng)用中必須有templates文件夾

模板語(yǔ)言

模板語(yǔ)言簡(jiǎn)稱為DTL(Django template language)

模板變量

模板變量名是由數(shù)字,字母,下劃線和點(diǎn)組成的,不能以下劃線開頭
模板變量使用:{{ 模板變量名 }}
模板變量的解析順序:
例如:{{ book.btitle }}

  1. 首先把book當(dāng)成一個(gè)字典,把btitle當(dāng)成鍵名,進(jìn)行取值book['btitle']
  2. 把book當(dāng)成一個(gè)對(duì)象,把btitle當(dāng)成屬性,進(jìn)行取值book.btitle
  3. 把book當(dāng)成一個(gè)對(duì)象,把btitle當(dāng)成對(duì)象的方法,進(jìn)行取值book.btitle
    例如:{{book.0}}

  4. 首先把book當(dāng)成一個(gè)字典,把0當(dāng)成鍵名,進(jìn)行取值book[0]
  5. 把book當(dāng)成一個(gè)列表,把0當(dāng)成下標(biāo),進(jìn)行取值book[0]
    如果解析失敗,則產(chǎn)生內(nèi)容時(shí)用空字符串填充模板變量
    使用模板變量時(shí),前面的可能是一個(gè)字典,可能是一個(gè)對(duì)象,還可能是一個(gè)列表
    vim models.py
from django.db import models

# Create your models here.
class BookInfo(models.Model):
    '''圖書模型類'''
    #圖書名稱
    btitle=models.CharField(max_length=20,db_column='btitle')
    #出版日期
    bpub_date=models.DateField()
    #閱讀量
    bread=models.IntegerField(default=0)
    #評(píng)論量
    bcomment=models.IntegerField(default=0)
    #刪除標(biāo)記
    isdelete=models.BooleanField(default=False)

vim views.py

from booktest.models import BookInfo
# /temp_var
def temp_var(request):
    '''模板變量'''
    my_dict={'title':'字典鍵值'}
    my_list=[1,2,3]
    book=BookInfo.objects.get(id=1)
    #定義模板上下文
    context={'my_dict':my_dict,'my_list':my_list,'book':book}
    return  render(request,'booktest/temp_var.html',context)

vim urls.py

from django.conf.urls import url
from booktest import views
urlpatterns = [
   url(r'^temp_var$',views.temp_var),#模板變量
]

vim temp_var.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板變量</title>
</head>
<body>
使用字典屬性:{{ my_dict.title }}<br/>
使用列表元素:{{ my_list.1 }}<br/>
使用對(duì)象屬性:{{ book.btitle }}<br/>
</body>
</html>
模板標(biāo)簽

模板代碼段:{% 代碼段 %}
for循環(huán):

{% for i in list %}

列表不為空時(shí)執(zhí)行

{% empty %}

列表為空時(shí)執(zhí)行

{% endfor %}

可以通過(guò){{ forloop.counter }}得到for循環(huán)遍歷到了第幾次

vim urls.py

from django.conf.urls import url
from booktest import views
urlpatterns = [
    url(r'^temp_tags$',views.temp_tags),
]

vim views.py

# /temp_tags
def temp_tags(request):
    '''模板標(biāo)簽'''
    #1. 查找所有圖書的信息
    books=BookInfo.objects.all()
    return render(request,'booktest/temp_tags.html',{'books':books})

vim temp_tags.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板標(biāo)簽</title>
</head>
<body>
<ul>
    {% for book in books %}
        <li>{{ forlop.counter }}--{{ book.btitle }}</li>
    {% endfor %}
</ul>
</body>
</html>
{% if 條件 %}
{% elif 條件 %}
{% else %}
{% endif %}

關(guān)系比較操作符:< > <= >= !=

注意:進(jìn)行比較時(shí),比較操作符兩邊必須有空格

邏輯運(yùn)算:not and or
vim temp_tags.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板標(biāo)簽</title>
    <style>
        .red {
            background-color: red;
        }
        .yellow {
            background-color: yellow;
        }
        .green {
            background-color: green;
        }
    </style>
</head>
<body>
<ul>
    {% for book in books %}
        {% if book.id <= 2 %}
            <li class="red">{{ forloop.counter }}--{{ book.btitle }}</li>
        {% elif book.id <= 4 %}
            <li class="yellow">{{ forloop.counter }}--{{ book.btitle }}</li>
        {% else %}
            <li class="green">{{ forloop.counter }}--{{ book.btitle }}</li>
        {% endif %}
    {% endfor %}
</ul>
</body>
</html>
模板過(guò)濾器

過(guò)濾器用于對(duì)模板變量進(jìn)行操作
date:改變?nèi)掌诘娘@示格式
length:求長(zhǎng)度。字符串,列表長(zhǎng)度
default:設(shè)置模板變量的默認(rèn)值
格式:模板變量|過(guò)濾器:參數(shù)
自定義過(guò)濾器。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板過(guò)濾器</title>
    <style>
        .red {
            background-color: red;
        }
        .green {
            background-color: green;
        }
    </style>
</head>
<body>
<ul>
    {% for book in books %}
        {% if book.id <= 2 %}
            <li class="red">{{ book.btitle }}--{{ book.bpub_date|date:'Y年-m月-d日' }}</li>
        {% else %}
            <li class="green">{{ book.btitle }}--{{ book.bpub_date }}</li>
        {% endif %}
    {% endfor %}
</ul>
default過(guò)濾器:<br/>
{{ content|default:'hello' }}
</body>
</html>
自定義模板過(guò)濾器

在應(yīng)用下創(chuàng)建一個(gè)包templatetags,包的名字固定,在包下創(chuàng)建一個(gè)過(guò)濾器文件
vim filters.py

#自定義過(guò)濾器
#過(guò)濾器其實(shí)就是python函數(shù)
from django.template import Library

#創(chuàng)建一個(gè)library類的對(duì)象
register=Library()
#自定義的過(guò)濾器函數(shù),最少有一個(gè)參數(shù),最多有兩個(gè)
@register.filter
def mod(num):
    '''判斷num是否為偶數(shù)'''
    return num%2 == 0

@register.filter
def mod_val(num,val):
    '''判斷num是否能被val整除'''
    return num%val ==0

vim temp_filters.html

<!DOCTYPE html>
<html lang="en">
{% load filters %}
<head>
    <meta charset="UTF-8">
    <title>模板過(guò)濾器</title>
    <style>
        .red {
            background-color: red;
        }
        .green {
            background-color: green;
        }
    </style>
</head>
<body>
<ul>
    {% for book in books %}
        {# {% if book.id <= 2 %} #}
        {# {% if book.id|mod %} #}
        {% if book.id|mod_val:3 %}
            <li class="red">{{ book.id }}--{{ book.btitle }}--{{ book.bpub_date|date:'Y年-m月-d日' }}</li>
        {% else %}
            <li class="green">{{ book.btitle }}--{{ book.bpub_date }}</li>
        {% endif %}
    {% endfor %}
</ul>
default過(guò)濾器:<br/>
{{ content|default:'hello' }}
</body>
</html>
模板注釋

單行注釋:{# 注釋內(nèi)容 #}
多行注釋:{% comment %}
注釋內(nèi)容
{% endcomment %}

模板繼承

把所有頁(yè)面相同的內(nèi)容放到父模板文件中,不需要放在塊中,有些位置頁(yè)面內(nèi)容不同,需要在父模板中預(yù)留塊。
在父模板里可以定義塊,使用標(biāo)簽:
{% block 塊名 %}
塊中間可以寫內(nèi)容,也可以不寫
{% endblock 塊名 %}
字模板去繼承父模板之后,可以重寫父模板中的某一塊內(nèi)容
繼承格式:

{% extends 父模板文件路徑 %}
{% block 塊名 %}
{{ block.super }} #獲取父模板中塊的默認(rèn)內(nèi)容
重寫的內(nèi)容
{% endblock 塊名 %}

vim views.py

#/temp_inherit
def temp_inherit(request):
    '''模板繼承'''
    return render(request,'booktest/child.html')

vim base.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>父模板文件</title>
</head>
<body>
<h2>導(dǎo)航條</h2>
{% block b1 %}
    <h2>這是父模板b1塊中</h2>
{% endblock b1 %}
<h2>版權(quán)信息</h2>
</body>
</html>

vim child.html

{% extends 'booktest/base.html' %}
{% block b1 %}
    {{ block.super }}
    <b1>這是子模板b1塊中的內(nèi)容</b1>
{% endblock b1 %}

vim urls.py

url(r'^temp_inherit$',views.temp_inherit), ##模板繼承
html轉(zhuǎn)義

編輯商品詳情信息,數(shù)據(jù)表中保存的是html內(nèi)容
在模板上下文中的html標(biāo)記默認(rèn)是會(huì)被轉(zhuǎn)義的

< 轉(zhuǎn)化為& lt;
> 轉(zhuǎn)換為& gt;
' 轉(zhuǎn)換為& #39;
" 轉(zhuǎn)換為& quot;
& 轉(zhuǎn)換為& amp;

要關(guān)閉模板上下文字符串的轉(zhuǎn)義:可以使用{{ 模板變量|safe }}
也可以使用
{% autoescape off %}
模板語(yǔ)言代碼
{% endautoescape %}

模板硬編碼中的字符串默認(rèn)不會(huì)經(jīng)過(guò)轉(zhuǎn)義,如果需要轉(zhuǎn)義,那需要手動(dòng)進(jìn)行轉(zhuǎn)義

vim views.py

def html_escape(request):
    '''HTML轉(zhuǎn)義'''
    return render(request,'booktest/html_escape.html',{'content':'<h2>hello</h2>'})

vim urls.py

 url(r'^html_escape$',views.html_escape), #HTML轉(zhuǎn)義

vim html_escap[e.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>html轉(zhuǎn)義</title>
</head>
<body>
{{ content }}
使用safe過(guò)濾器關(guān)閉轉(zhuǎn)義:<br/>
{{ content|safe }}
</br>
模板硬編碼中的字符串不會(huì)經(jīng)過(guò)轉(zhuǎn)義<br/>
{{ test|default:'<h2>hello</h2>' }}<br/>
手動(dòng)進(jìn)行轉(zhuǎn)義:<br/>
{{ test|default:'<h2>hello</h2>' }}
</body>
</html>
csrf***

首先做一個(gè)登錄頁(yè),讓用戶輸入用戶名和密碼進(jìn)行登錄,登陸成功之后跳轉(zhuǎn)的修改密碼頁(yè)面。在修改密碼頁(yè)面輸入新密碼,點(diǎn)擊確認(rèn)按鈕完成密碼修改
登錄頁(yè)需要一個(gè)模板文件login.html,修改密碼頁(yè)面也需要一個(gè)模板文件
change_pwd.html
顯示登錄頁(yè)的視圖login,驗(yàn)證登錄的視圖login_check,顯示發(fā)帖頁(yè)的視圖change_pwd,處理修改密碼的視圖change_pwd_action
加功能:

  1. 只有用戶登錄之后才可以進(jìn)行發(fā)帖操作
    登錄裝飾器函數(shù)

vim views.py

def login_required(view_func):
    '''登錄判斷裝飾器'''
    def wrapper(request,*views_args,**view_kwargs):
        #判斷用戶是否登錄
        if request.session.has_key('islogin'):
            #用戶已登錄,調(diào)用對(duì)應(yīng)的視圖
            return view_func(request,*views_args,**view_kwargs)
        else:
            #用戶未登錄,跳轉(zhuǎn)到登錄頁(yè)
            return redirect('/login')
    return wrapper
def login(request):
    '''顯示登錄頁(yè)面'''
    #判斷用戶是否登錄
    if request.session.has_key('islogin'):
        return redirect('/index')
    else:
        #用戶未登錄
        #獲取cookie username
        if 'username' in request.COOKIES:
            #獲取記住的用戶名
            username = request.COOKIES['username']
        else:
            username=''
        return render(request,'booktest/login.html',{'username':username})

def login_check(request):
    '''登錄校驗(yàn)視圖'''

    username=request.POST.get('username')
    password=request.POST.get('password')
    remember=request.POST.get('remember')
    #2. 進(jìn)行登錄的校驗(yàn)
    #實(shí)際開發(fā):根據(jù)用戶和密碼查找數(shù)據(jù)庫(kù)
    #模擬:smart 123
    if username=='smart' and password=='123':
        #用戶名密碼正確,跳轉(zhuǎn)到首頁(yè)
        response=redirect('/index')
        #判斷是否需要記住用戶名
        if remember == 'on':
            #設(shè)置cookie username,過(guò)期時(shí)間為一周
            response.set_cookie('username',username,max_age=7*24*3600)
        #記住用戶登錄狀態(tài)
        #只有session中有islogin,就認(rèn)為用戶已登錄
        request.session['islogin']=True
        #記住登錄的用戶名
        request.session['username']=username

        return response
    else:
        #用戶名或密碼錯(cuò)誤,跳轉(zhuǎn)到登錄頁(yè)面
        request.session['username']=username
        return redirect('/change_pwd')

# /change_pwd
@login_required
def change_pwd(request):
    '''顯示修改密碼頁(yè)面'''
    return render(request,'booktest/change_pwd.html')

# /change_pwd_action
@login_required
def change_pwd_action(request):
    '''模擬修改密碼處理'''
    # 1.獲取新密碼
    pwd=request.POST.get('pwd')
    #獲取用戶名
    username=request.session.get('username')
    #2.實(shí)際開發(fā)的時(shí)候:修改對(duì)應(yīng)數(shù)據(jù)庫(kù)的內(nèi)容
    #3.返回一個(gè)應(yīng)答
    return HttpResponse('%s修改密碼為:%s' %(username,pwd))

vim urls.py

url(r'^login$',views.login), #顯示登錄頁(yè)面
    url(r'^login_check$',views.login_check), #進(jìn)行登錄校驗(yàn)
    url(r'^change_pwd$',views.change_pwd), #修改密碼頁(yè)面顯示
    url(r'^change_pwd_action$',views.change_pwd_action), #修改密碼處理

vim login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄頁(yè)面</title>
</head>
<body>
<form method="post" action="/login_check">
    用戶名:<input type="text" name="username" value="{{ username }}"><br/>
    密碼:<input type="password" name="password"><br/>
    <input type="checkbox" name="remember">記住用戶名<br/>
    <input type="submit" value="登錄">
</form>
</body>
</html>

vim change_pwd.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>修改密碼界面</title>
</head>
<body>
<form method="post" action="/change_pwd_action">
    新密碼:<input type="password" name="pwd">
    <input type="submit" value="確認(rèn)修改">
</form>
</body>
</html>
django防止csrf的方式:
  1. 默認(rèn)打開CSRF中間件
  2. 表單post提交數(shù)據(jù)時(shí)加上{% csrf_token %}標(biāo)簽

防御原理:

  1. 渲染模板文件時(shí)在頁(yè)面生成一個(gè)名字叫做csrfmiddlewaretoken的隱藏域
  2. 服務(wù)器交給瀏覽器保存一個(gè)名字為csrftoken的cookie信息
  3. 提交表單時(shí),兩個(gè)值都會(huì)發(fā)給服務(wù)器,服務(wù)器進(jìn)行比對(duì),如果一樣,則csrf驗(yàn)證通過(guò),否則失敗
驗(yàn)證碼

vim views.py

def login_check(request):
    '''登錄校驗(yàn)視圖'''

    username=request.POST.get('username')
    password=request.POST.get('password')
    remember=request.POST.get('remember')
    #獲取用戶輸入驗(yàn)證碼
    vcode1=request.POST.get('vcode')
    #獲取session中保存的驗(yàn)證碼
    vcode2=request.session.get('verifycode')
    #進(jìn)行驗(yàn)證碼校驗(yàn)
    if vcode1 != vcode2:
        #驗(yàn)證碼錯(cuò)誤
        return redirect('/login')
    #2. 進(jìn)行登錄的校驗(yàn)
    #實(shí)際開發(fā):根據(jù)用戶和密碼查找數(shù)據(jù)庫(kù)
    #模擬:smart 123
    if username=='smart' and password=='123':
        #用戶名密碼正確,跳轉(zhuǎn)到首頁(yè)
        response=redirect('/index')
        #判斷是否需要記住用戶名
        ...
#/驗(yàn)證碼
from PIL import Image,ImageDraw,ImageFont
from django.utils.six import BytesIO
def verify_code(request):
    #引入隨機(jī)函數(shù)模塊
    import random
    #定義變量,用于畫面的背景色、寬、高
    bgcolor=(random.randrange(20,100),random.randrange(20,100),255)
    width=100
    height=25
    #構(gòu)建畫面圖像
    im=Image.new('RGB',(width,height),bgcolor)
    #創(chuàng)建畫筆對(duì)象
    draw=ImageDraw.Draw(im)
    #調(diào)用畫筆的point()函數(shù)繪制噪點(diǎn)
    for i in range(0,100):
        xy=(random.randrange(0,width),random.randrange(0,height))
        fill=(random.randrange(0,255),255,random.randrange(0,255))
        draw.point(xy,fill=fill)
    #定義驗(yàn)證碼的備選值
    str1='ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
    #隨機(jī)選取4個(gè)值作為驗(yàn)證碼
    rand_str=''
    for i in range(0,4):
        rand_str+=str1[random.randrange(0,len(str1))]

    #構(gòu)造字體對(duì)象
    font=ImageFont.truetype('/usr/share/fonts/gnu-free/FreeMonoBold.ttf',23)
    #構(gòu)造字體的顏色
    fontcolor=(255,random.randrange(0,255),random.randrange(0,255))
    #繪制四個(gè)字
    draw.text((5,2),rand_str[0],font=font,fill=fontcolor)
    draw.text((25,2),rand_str[1],font=font,fill=fontcolor)
    draw.text((50, 2), rand_str[2], font=font, fill=fontcolor)
    draw.text((75, 2), rand_str[3], font=font, fill=fontcolor)
    #釋放畫筆
    del draw
    #存入session,用于做進(jìn)一步驗(yàn)證
    request.session['verifycode']=rand_str
    #內(nèi)存文件操作
    buf=BytesIO()
    #將圖片保存在內(nèi)存中,文件類型是png
    im.save(buf,'png')
    #將內(nèi)存中的圖片數(shù)據(jù)返回給客戶端,mime類型為圖片png
    return HttpResponse(buf.getvalue(),'image/png')

vim login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄頁(yè)面</title>
</head>
<body>
<form method="post" action="/login_check">
    {% csrf_token %}
    用戶名:<input type="text" name="username" value="{{ username }}"><br/>
    密碼:<input type="password" name="password"><br/>
    <input type="checkbox" name="remember">記住用戶名<br/>

    <img src="/verify_code"><input type="text" name="vcode"><br/>
    <input type="submit" value="登錄">
</form>
</body>
</html>
反向解析

當(dāng)某一個(gè)url配置的地址發(fā)生變化時(shí),頁(yè)面上使用反向解析生成地址的位置不需要發(fā)生變化
根據(jù)url正則表達(dá)式的配置動(dòng)態(tài)的生成url

vim booktest/views.py

url(r'^url_reverse$',viewa.url_reverse), #反向解析頁(yè)面

模型

創(chuàng)建模型類

vim models.py

from django.db import models

# Create your models here.
class BookInfo(models.Model):
    '''圖書模型類'''
    #圖書名稱
    btitle=models.CharField(max_length=20)
    #出版日期
    bpub_date=models.DateField()
    #閱讀量
    bread=models.IntegerField(default=0)
    #評(píng)論量
    bcomment=models.IntegerField(default=0)
    #刪除標(biāo)記
    isdelete=models.BooleanField(default=False)

class HeroInfo(models.Model):
    '''英雄人物模型類'''
    #英雄名
    hname=models.CharField(max_length=20)
    #性別
    hgender=models.BooleanField(default=False)
    #備注
    hcomment=models.CharField(max_length=200)
    #關(guān)系屬性
    hbook=models.ForeignKey('BookInfo',on_delete=models.CASCADE,)
    # 刪除標(biāo)記
    isdelete=models.BooleanField(default=False)

執(zhí)行遷移文件生成表

python manage.py makemigrations
python manage.py migrate

往數(shù)據(jù)表里插入數(shù)據(jù)

insert into booktest_bookinfo(btitle,bpub_date,bread,bcomment,isdelete) values
    -> ('射雕英雄傳','1980-5-1',12,34,0),
    -> ('天龍八部','1986-7-24',36,40,0),
    -> ('笑傲江湖','1995-12-24',20,80,0),
    -> ('雪山飛狐','1987-11-11',58,24,0);
insert into booktest_heroinfo(hname,hgender,hbook_id,hcomment,isdelete) valu s 掌0) ('郭靖',1,1,'降龍十八掌',0), ('黃蓉',0,1,'打狗棍法',0), ('黃藥師',1,1,'彈指神  姐姐 ('歐陽(yáng)鋒',1,1,'蛤蟆功',0), ('梅超風(fēng)',0,1,'九陰白骨爪',0) ,('喬峰',1,2,'降龍十  劍法',0), ('段譽(yù)',1,2,'六脈神劍',0), ('虛竹',1,2,'天山折梅手',0), ('王語(yǔ)嫣',0,2,'神 黃衣',,0), ('令狐沖',1,3,'獨(dú)孤九劍',0), ('任盈盈',0,3,'彈琴',0), ('岳不群',1,3,'華.劍Query OK, 17 rows affected (0.00 sec)), ('胡斐',1,4,'胡家刀法',0), ('苗春蘭',0,4,'黃衣Records: 17  Duplicates: 0  Warnings: 00,4,'六合拳',0);
設(shè)計(jì)url,通過(guò)url瀏覽器訪問(wèn)url/index時(shí)顯示圖書信息頁(yè)面

vim index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>圖書信息</title>
</head>
<body>
<a href="/create">新增</a>
<ul>
    {% for book in books %}
        <li>{{ book.btitle }}--<a href="/delete{{ book.id }}">刪除</a></li>
    {% endfor %}
</ul>

</body>
</html>

vim booktest/views.py

from django.shortcuts import render,redirect 
from booktest.models import BookInfo  
from datetime import date
from django.http import HttpResponse,HttpResponseRedirect
# Create your views here.
def index(request):
    '''顯示圖書信息'''
    #1. 查詢出所有圖書的信息
    books=BookInfo.objects.all()
    #2.使用模板
    return render(request,'booktest/index.html',{'books':books})
def create(request):
    '''新增一本圖書'''
    #1.創(chuàng)建BookInfo對(duì)象
    b=BookInfo()
    b.btitle='流星蝴蝶劍'
    b.bpub_date=date(1990,1,1)
    #2.保存進(jìn)數(shù)據(jù)庫(kù)
    b.save()
    #3.返回應(yīng)答,讓瀏覽器再訪問(wèn)/index
    return HttpResponse('ok')
    #return HttpResponseRedirect('/index')
def delete(request,bid):
    '''刪除點(diǎn)擊的圖書'''
    #1.通過(guò)bid獲取圖書對(duì)象
    book=BookInfo.objects.get(id=bid)
    #2.刪除
    book.delete()
    #3.重定向,讓瀏覽器訪問(wèn)/index
    #return HttpResponseRedirect('/index')
    return redirect('/index')

vim test2/urls.py

from django.contrib import admin
#from django.urls import path
from django.conf.urls import include,url
urlpatterns = [
    url(r'^admin/',admin.site.urls),#配置項(xiàng)
    url(r'^',include('booktest.urls')) #包含test1應(yīng)用中的urls文件
]

vim booktest/urls.py

from django.conf.urls import url
from booktest import views

urlpatterns=[
    url(r'^index$',views.index), #圖書信息頁(yè)面
    url(r'^create$',views.create), #添加圖書信息
    url(r'^delete(\d+)$',views.delete), #刪除點(diǎn)擊的圖書
]

查詢

修改mysql的日志文件:
讓其產(chǎn)生mysql.log,即是mysql的日志文件,里面記錄的對(duì)mysql數(shù)據(jù)庫(kù)的操作記錄

  1. 使用下面的命令打開mysql的配置文件,編輯general_log=1 general_log_file= /usr/local/mysql/data/mysql.log,然后保存vi /etc/my.cnf
  2. 重啟mysql服務(wù),就會(huì)產(chǎn)生mysql日志文件mysql.server start
  3. 打開mysql的日志文件
    tail /usr/local/mysql/data/mysql.log
查詢函數(shù)

通過(guò)模型類.objects屬性可以調(diào)用如下函數(shù),實(shí)現(xiàn)對(duì)模型類對(duì)應(yīng)的數(shù)據(jù)表的查詢

函數(shù)名 功能 返回值 說(shuō)明
get 返回表中滿足條件的一條且只能有一條數(shù)據(jù) 返回值是一個(gè)模型類對(duì)象 參數(shù)中寫查詢條件 1.如果查到多條數(shù)據(jù),則拋異常multipleobjectreturned。2.查詢不到數(shù)據(jù),則拋異常:doesnotexist
all 返回模型類對(duì)應(yīng)表格中的所有數(shù)據(jù) 返回值是queryset類型 查詢集
filter 返回滿足條件的數(shù)據(jù) 返回值是queryset類型 參數(shù)寫查詢條件
exclude 返回不滿足條件的數(shù)據(jù) 返回值是queryset類型 參數(shù)寫查詢條件
order_by 對(duì)查詢結(jié)果進(jìn)行排序 返回值是queryset類型 參數(shù)中寫根據(jù)哪些字段進(jìn)行排序
filter方法示例:
  • 條件格式:模型類屬性名__條件名=值
    • 判等 條件名:exact
      • 查詢編號(hào)為1的圖書
      • BookInfo.objects.get(id__exact=1)
    • 模糊查詢
      • 查詢書名包含傳的圖書
      • BookInfo.objects.filter(btitle__contains='傳')
      • 查詢書名以'部'結(jié)尾的圖書endswith開頭:startswith
      • BookInfo.objects.filter(btitle__endswith='部')
    • 空查詢isnull
      • 查詢書名不為空的圖書
      • BookInfo.objects.filter(btitle__isnull=False)
    • 范圍查詢
      • 查詢id為1或3或5的圖書
      • BookInfo.objects.filter(id__in=[1,3,5])
    • 比較查詢gt、lt、gte、lte
      • 查詢編號(hào)大于3的圖書
      • BookInfo.objects.filter(id__gt=3)
    • 日期查詢
      • 查詢1980年發(fā)表的圖書
      • BookInfo.objects.filter(bpub_date__year=1980)
      • 查詢1980年1月1日后發(fā)表的書
      • from datetime importdate
      • BookInfo.objects.filter(bpub_date__gt=date(1980,1,1))
order by方法示例
  • 作用:進(jìn)行查詢結(jié)果的排序
    • 查詢所有圖書信息,按照id從小到大進(jìn)行排序
    • BookInfo.objects.all().order_by('id')
    • 查詢所有圖書的信息,按照id從大到小進(jìn)行排序
    • BookInfo.objects.all().order_by('-id')
    • 把id大于3的圖書信息按閱讀量從大到小進(jìn)行排序
    • BookInfo.objects.filter(id__gt=3).order_by('-bread')

Q對(duì)象

作用:用于查詢時(shí)條件之間的邏輯關(guān)系。mot and or,可以對(duì)Q對(duì)象進(jìn)行&|~操作
使用之前需要先導(dǎo)入:
from Django.db.models import Q
例:查詢id大于3且閱讀量大于30的圖書的信息
BookInfo.objects.filter(id__gt=3,bread__gt=30)
BookInfo.objects.filter(Q(id__gt=3)&Q(bread__gt=30))
例:查詢id大于3或者閱讀量大于30的圖書的信息
BookInfo.objects.filter(Q(id__gt=3)|Q(bread__gt=30))
例:查詢id不等于3圖書的信息
BookInfo.objects.filter(~Q(id=3))

F對(duì)象

作用:用于類屬性之間的比較
使用之前需要先導(dǎo)入:
from django.db.models import F
例:查詢圖書閱讀量大于評(píng)論量圖書的信息
BookInfo.objects.filter(bread__gt=F('bcomment'))
例:查詢圖書閱讀量大于2倍評(píng)論量圖書信息
BookInfo.objects.filter(bread__gt=F('bcomment')*2)

聚合函數(shù)

作用:對(duì)查詢結(jié)果進(jìn)行聚合操作
sum count avg max min
aggregate:調(diào)用這個(gè)函數(shù)來(lái)使用聚合。返回值是一個(gè)字典。
使用前需先導(dǎo)入聚合類:
from django.db.models import Sum,Count,Max,Min,Avg
例:查詢所有圖書的數(shù)目

select count(*) from booktest_bookinfo;
BookInfo.objects.all().aggregate(Count('id'))
BookInfo.objects.aggregate(Count('id'))

例:查詢所有圖書閱讀量的總和
BookInfo.objects.aggregate(Sum('bread'))

查詢集

all,filter,exclude,order_by調(diào)用這些函數(shù)會(huì)產(chǎn)生一個(gè)查詢集
QuerySet類對(duì)象可以繼續(xù)調(diào)用上面的所有函數(shù)

查詢集特性:
  1. 惰性查詢:只有在實(shí)際使用查詢集中的數(shù)據(jù)的時(shí)候才會(huì)發(fā)生對(duì)數(shù)據(jù)庫(kù)的真正查詢
  2. 緩存:當(dāng)使用的是同一個(gè)查詢集時(shí),第一次的時(shí)候會(huì)發(fā)生實(shí)際數(shù)據(jù)庫(kù)的查詢,然后把結(jié)果緩存起來(lái),之后再使用這個(gè)查詢集時(shí),使用的是緩存中的結(jié)果。
限制查詢集

可以對(duì)一個(gè)查詢集進(jìn)行取下標(biāo)或者切片操作來(lái)限制查詢集的結(jié)果
對(duì)一個(gè)查詢集進(jìn)行切片操作會(huì)產(chǎn)生一個(gè)新的查詢集,下標(biāo)不允許為負(fù)數(shù)。
取出查詢集第一條數(shù)據(jù)的兩種方式:

方式 說(shuō)明
b[0] 如果b[0]不存在,會(huì)拋出IndexError異常
b[0:1].get() 如果b[0:1].get()不存在,會(huì)拋出DoesNotExist異常
  • exists:判斷一個(gè)查詢集中是否有數(shù)據(jù)。True False

模型類關(guān)系

  1. 一對(duì)多關(guān)系
    例:圖書類-英雄類
    models.ForeignKey()定義多的類中
    1. 多對(duì)多關(guān)系
      例:新聞?lì)?新聞?lì)愋皖?體育新聞 國(guó)際新聞
      models.ManyToManyField()定義在哪個(gè)類中都可以
    2. 一對(duì)一關(guān)系
      例:?jiǎn)T工基本信息表-員工詳細(xì)信息類
      models.OneToOneField定義在哪個(gè)類中都可以

關(guān)聯(lián)查詢(一對(duì)多)

在一對(duì)多關(guān)系中,一對(duì)應(yīng)的類我們把他叫做一類,多對(duì)應(yīng)的類我們把它叫做多類,我們把多類中定義的建立關(guān)聯(lián)的類屬性叫做關(guān)聯(lián)屬性。
例:查詢id為1的圖書關(guān)聯(lián)的英雄的信息。

b=BookInfo.objects.get(id=1)
b.heroinfo_set.all()

通過(guò)模型類查詢:
HeroInfo.objects.filter(hbook__id=1)
例:查詢id為1的英雄關(guān)聯(lián)的圖書信息

h=HeroInfo.objects.get(id=1)
h.hbook()

通過(guò)模型類查詢:
BookInfo.objects.filter(heroinfo__id=1)

通過(guò)模型類查詢
  • 由一類的對(duì)象查詢多類的時(shí)候
    • 一類的對(duì)象.多類名小寫_set.all() #查詢所用數(shù)據(jù)
  • 由多類的對(duì)象查詢一類的時(shí)候
    • 多類的對(duì)象.關(guān)聯(lián)屬性 #查詢多類的對(duì)象對(duì)應(yīng)的一類的對(duì)象
  • 由多類的對(duì)象查詢一類的對(duì)象的id的時(shí)候
    • 多類的對(duì)象.關(guān)聯(lián)屬性_id

插入、更新和刪除

  • 調(diào)用一個(gè)模型類對(duì)象的save方法的時(shí)候就可以實(shí)現(xiàn)對(duì)模型類對(duì)應(yīng)數(shù)據(jù)表的插入和更新
  • 調(diào)用一個(gè)模型類對(duì)象的delete方法的時(shí)候就可以實(shí)現(xiàn)對(duì)模型類對(duì)應(yīng)數(shù)據(jù)表數(shù)據(jù)的刪除

自關(guān)聯(lián)

自關(guān)聯(lián)是一種特殊的一對(duì)多的關(guān)系

管理器

BookInfo.objects.all()->ojects是一個(gè)什么東西呢?
答:

  • objects是Django幫我自動(dòng)生成的管理器對(duì)象,通過(guò)這個(gè)管理器可以實(shí)現(xiàn)對(duì)數(shù)據(jù)的查詢
  • objects是models.Manger類的一個(gè)對(duì)象。自定義管理器之后Django不再幫我們生成默認(rèn)的objects管理器
    1. 自定義一個(gè)管理器類,這個(gè)類繼承models.Manger類
    2. 再在具體的模型類里定義一個(gè)自定義管理器類的對(duì)象
      class BookInfoManager(models.Manager):
      '''圖書模型管理器類'''
      # 1.改變查詢的結(jié)果集
      def all(self):
      #1.調(diào)用父類的all,獲取所有數(shù)據(jù)
      books=super().all() #QuerySet
      #2. 對(duì)數(shù)據(jù)進(jìn)行過(guò)濾
      books=books.filter(isDelete=False)
      #3.返回books
      return books
      #2.封裝函數(shù):操作模型類對(duì)應(yīng)的數(shù)據(jù)表(增刪改查)
      def create_book(self,btitle,bpub_date):
      #1.創(chuàng)建一個(gè)圖書對(duì)象
      model_class=self.model
      book=model_class()
      #book=BookInfo()
      book.btitle=btitle
      book.bpub_date=bpub_date
      #2.保存進(jìn)數(shù)據(jù)庫(kù)
      book.save()
      #3.返回book
      return book 
      自定義管理器類的應(yīng)用場(chǎng)景
    3. 改變查詢的結(jié)果集
      • 比如調(diào)用BookInfo.boks.all()返回的是沒(méi)有刪除的圖書的數(shù)據(jù)
    4. 添加額外的方法
      • 管理器類中定義一個(gè)方法幫我們操作模型類對(duì)應(yīng)的數(shù)據(jù)表
      • 使用self.model()就可以創(chuàng)建一個(gè)跟自定義管理器對(duì)應(yīng)的模型 類對(duì)象

元選項(xiàng)

  • Django默認(rèn)生成的表名:
    • 應(yīng)用名小寫_模型類名小寫
  • 元選項(xiàng):
    • 需要在模型類中定義一個(gè)Meta,在里面定義一個(gè)類屬性db_table就可以指定表名
  • 以BookInfo模型類為例,在BookInfo中定義一個(gè)元類
    class BookInfo(models.Model):
    class Meta:
        db_table='bookinfo'

其他

靜態(tài)文件

使用

在網(wǎng)頁(yè)使用的css文件,js文件和圖片叫做靜態(tài)文件

新建靜態(tài)文件夾
  • static
    • images
    • css
    • js
配置靜態(tài)文件所在的物理目錄。

vim settings.py

#設(shè)置訪問(wèn)靜態(tài)文件對(duì)應(yīng)的url地址
STATIC_URL = '/static/'
#設(shè)置靜態(tài)文件存放的物理目錄
STATICFILES_DIRS=[os.path.join(BASE_DIR,'static')]

vim static_test.html

<!DOCTYPE html>
{% load staticfiles %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>靜態(tài)文件</title>
</head>
<body>
<img src="/static/images/mm.jpg"><br/>
動(dòng)態(tài)獲取STATIC_URL,拼接靜態(tài)文件路徑:<br/>
<img src="{% static 'images/mm.jpg' %}">
</body>
</html>

vim views.py

from django.shortcuts import render
from django.conf import settings
# Create your views here.
# /static_test
def static_test(request):
    '''靜態(tài)文件'''
    print(settings.STATICFILES_FINDERS)
    return render(request,'booktest/static_test.html')

vim urls.py

from django.conf.urls import url
from booktest import views

urlpatterns = [
    url(r'^static_test$',views.static_test), #靜態(tài)文件
]
加載目錄
STATICFILES_FINDERS=('django.contrib.staticfiles.finders.FileSystemFinder','django.contrib.staticfiles.finders.AppDirectoriesFinder')

中間件

中間件函數(shù)是Django框架給我們預(yù)留的函數(shù)接口,讓我們可以干預(yù)請(qǐng)求和應(yīng)答的過(guò)程

獲取瀏覽器端的ip地址

使用request對(duì)象的meta屬性:request.META['REMOTE_ADDR']

使用中間件
新建middleware.py文件

vim booktest/middleware.py

定義中間件類
  • 在類中定義中間件預(yù)留函數(shù)
    • __init__:服務(wù)器響應(yīng)第一個(gè)請(qǐng)求的時(shí)候調(diào)用
    • process_request:是在產(chǎn)生request對(duì)象,進(jìn)行url匹配之前調(diào)用
    • process_view:是url匹配之后,調(diào)用視圖函數(shù)之前
    • process_response:視圖函數(shù)調(diào)用之后,內(nèi)容返回給瀏覽器之前
    • process_exception:視圖函數(shù)出現(xiàn)異常,會(huì)調(diào)用這個(gè)函數(shù)

如果注冊(cè)的多個(gè)中間件類中包含process_exception函數(shù)的時(shí)候,調(diào)用的順序跟注冊(cè)的順序是相反的

vim booktest/middleware.py

from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin
class BlockedIPSMiddleware(object):
    EXCLUDE_IPS=['223.71.207.106']
    def process_view(self,request,view_func,*view_arg,**view_kwargs):
        '''視圖函數(shù)調(diào)用之前會(huì)調(diào)用'''
        user_ip=request.META['REMOTE_ADDR']
        if user_ip in BlockedIPSMiddleware.EXCLUDE_IPS:
            return HttpResponse('<h2>Forbidden</h2>')
注冊(cè)中間件類

vim settings.py

MIDDLEWARE = [
    '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',
    'booktest.middleware.BlockedIPSMiddleware', #注冊(cè)中間件類
]

上傳圖片

配置上傳文件保存目錄
  1. 新建上傳文件保存目錄
    在static下創(chuàng)建目錄media/booktest
  2. 配置上傳文件保存目錄
    vim settings.py
    #設(shè)置上傳文件的保存目錄
    MEDIA_ROOT=os.path.join(BASE_DIR,'static/media')
后臺(tái)管理頁(yè)面上傳圖片
設(shè)計(jì)模型類

vim models.py

from django.db import models

# Create your models here.
class PicTest(models.Model):
    '''上傳圖片'''   goods_pic=models.ImageField(upload_to='booktest')
遷移生成表格

python manage.py makimigrations
python manage.py migrate

注冊(cè)模型類

vim admin.py

from django.contrib import admin
from booktest.models import PicTest
admin.site.register(PicTest)
自定義頁(yè)面上傳
  1. 定義用戶上傳圖片的頁(yè)面并顯示,是一個(gè)自定義的表單

vim upload_pic.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上傳圖片</title>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="upload_handle">
    {% csrf_token %}
    <input type="file" name="pic"><br/>
    <input type="submit" value="上傳">
</form>
</body>
</html>
  1. 定義接收上傳文件的視圖函數(shù)
    request對(duì)象有一個(gè)FILES的屬性,類似于字典,通過(guò)request.FILES可以獲取上傳文件的處理對(duì)象

vim views.py

from booktest.models import PicTest
def show_upload(request):
    '''顯示上傳圖片頁(yè)面'''
    return render(request,'booktest/upload_pic.html')

def upload_handle(request):
    '''上傳圖片處理'''
    # 1.獲取上傳的圖片
    pic =request.FILES['pic']
    #print (pic.name)
    #2.創(chuàng)建一個(gè)文件
    save_path= '%s/booktest/%s' %(settings.MEDIA_ROOT,pic.name)
    with open(save_path,'wb') as f:
        #3.獲取上傳文件的內(nèi)容并寫到創(chuàng)建的文件中
        for content in pic.chunks():
            f.write(content)
    #4. 在數(shù)據(jù)庫(kù)中保存上傳記錄
    PicTest.objects.create(goods_pic='booktest/%s' %pic.name)
    #5.返回
    return HttpResponse('ok')

上傳文件不大于2.5M,文件放在內(nèi)存中
上傳文件大于2.5M,文件內(nèi)容寫到一個(gè)臨時(shí)文件中

分頁(yè)

查詢出所有省級(jí)地區(qū)的信息,顯示在頁(yè)面上。
AreaInfo.objects.filter(aparent_isnull)

  1. 查詢出所有省級(jí)地區(qū)的信息
  2. 按每頁(yè)顯示10條信息進(jìn)行分頁(yè),默認(rèn)顯示第一頁(yè)的信息,下面并顯示出頁(yè)碼
  3. 點(diǎn)擊i頁(yè)鏈接的時(shí)候,就顯示第i頁(yè)的省級(jí)地區(qū)信息。
from django.core.paginator import Paginator
paginator=Paginator(areas,10) #按每頁(yè)10條數(shù)據(jù)進(jìn)行分頁(yè)

Paginator類對(duì)象的屬性

屬性名 說(shuō)明
num_pages 返回分頁(yè)之后的總頁(yè)數(shù)
page_range 返回分頁(yè)頁(yè)碼的列表

Paginator

方法名 說(shuō)明
page(self,number) 返回第number頁(yè)的page類實(shí)例對(duì)象

Page類對(duì)象的屬性

屬性名 說(shuō)明
number 返回當(dāng)前頁(yè)的頁(yè)碼
object_list 返回包含當(dāng)前頁(yè)的數(shù)據(jù)的查詢
paginator 返回對(duì)應(yīng)的Paginator類對(duì)象

Page類對(duì)象的方法

屬性名 說(shuō)明
has_previous 判斷當(dāng)前頁(yè)是否有前一頁(yè)
has_next 判斷當(dāng)前頁(yè)是否有下一頁(yè)
previous_page_number 返回前一頁(yè)的頁(yè)碼
next_page_number 返回下一頁(yè)的頁(yè)碼
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI