Django 框架 第二章

1,Django  框架中新建的app應用,必定先去settings.py註冊css

        INSTALLED_APPS = [
                'django.contrib.admin',
                'django.contrib.auth',
                'django.contrib.contenttypes',
                'django.contrib.sessions',
                'django.contrib.messages',
                'django.contrib.staticfiles',
                # 'app01'  # 簡寫
                'app01.apps.App01Config'  # 全稱
            ]

## 注意事項:html

2, html文件默認全都放在templates文件夾下前端

 

對於前段已經寫好了的文件 咱們只是拿過來使用 那麼這些文件均可以稱之爲叫"靜態文件"python

靜態文件能夠是mysql

bootstrap一類的前段框架 已經寫好了的git

圖片正則表達式

csssql

js數據庫

靜態文件默認全都放在static文件夾下django

static文件夾中默認會默認建立的子文件夾

css文件夾  當前網站全部的樣式文件

js文件  當前網站全部的js文件

img文件  當前網站全部的圖片文件

其餘(前端框架代碼 第三方插件代碼...)

 

 

啓動ddjango項目的時候 必定要確保一個端口號只有一個django項目在佔用

否則的話 會容易形成bug、

 

用戶能夠訪問的資源 都在url中

只有url中開設相關的資源你才能訪問到(******)

後端資源通常都須要手動指定是否須要暴露給用戶

 

## 3 靜態文件配置

 

STATICFILES_DIRS = [
            os.path.join(BASE_DIR,'static')
    ]
    ##你只要輸入static文件夾內具體文件的路徑就可以訪問到

 

 # 

STATIC_URL = '/static/'  # 這個static不是文件夾的名字 而是接口前綴

 """只要你想訪問靜態文件中的資源 文件路徑就必須用static開頭"""

 # 手動將static文件夾中全部的資源暴露給用戶

 STATICFILES_DIRS = [

  os.path.join(BASE_DIR,'static'),  # 真正的文件夾路徑

  os.path.join(BASE_DIR,'static1'),  # 真正的文件夾路徑

  os.path.join(BASE_DIR,'static2'),  # 真正的文件夾路徑

  os.path.join(BASE_DIR,'static3')  # 真正的文件夾路徑

 ]

 

 

 

##

django默認是支持自動重啓代碼的 因此你只須要多刷新幾回頁面就能夠

可是有時候它的重啓機制比較慢

機制:實時監測文件代碼變化 只要有變化 就會自動重啓 

可能你的代碼尚未寫完 這個時候就會自動報錯

 

##

靜態文件接口前綴"動態解析"

##靜態文件接口前綴"動態解析"
        {% load static %}

        <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
##    利用解析器 動態獲取接口前綴 

##

重點!

form表單默認是get請求

攜帶數據的方式是url問好後跟數據

http://127.0.0.1:8000/login/?username=zekai&password=123

 

  

能夠經過method改成post請求

改爲post請求以後 須要去settings文件中註釋掉一箇中間件

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',
        ]

##

form 表單提交數據的由 action 的三種方法:

1.不寫的狀況下 默認往當前地址提交

2.還能夠寫後綴/index/(將項目經常使用這種)

 

3.還能夠寫全路徑

 

 

##

 

Django的路由系統

 

 

參數說明:

  • 正則表達式:一個正則表達式字符串
  • views視圖函數:一個可調用對象,一般爲一個視圖函數或一個指定視圖函數路徑的字符串
  • 參數:可選的要傳遞給視圖函數的默認參數(字典形式)
  • 別名:一個可選的name參數

正則表達式詳解

from django.conf.urls import url

from . import views

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. urlpatterns中的元素按照書寫順序從上往下逐一匹配正則表達式,一旦匹配成功則再也不繼續。
  2. 若要從URL中捕獲一個值,只須要在它周圍放置一對圓括號(分組匹配)。
  3. 不須要添加一個前導的反斜槓,由於每一個URL 都有。例如,應該是^articles 而不是 ^/articles。
  4. 每一個正則表達式前面的'r' 是可選的可是建議加上。
# 是否開啓URL訪問地址後面不爲/跳轉至帶有/的路徑的配置項
APPEND_SLASH=True

Django settings.py配置文件中默認沒有 APPEND_SLASH 這個參數,但 Django 默認這個參數爲 APPEND_SLASH = True。 其做用就是自動在網址結尾加'/'。

其效果就是:

咱們定義了urls.py:

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

urlpatterns = [
        url(r'^blog/$', views.blog),
]

訪問 http://www.example.com/blog 時,默認將網址自動轉換爲 http://www.example/com/blog/ 。

若是在settings.py中設置了 APPEND_SLASH=False,此時咱們再請求 http://www.example.com/blog 時就會提示找不到頁面。

##  

視圖函數通常主要會先處理get請求

        def login(request):
            # 視圖函數針對不一樣的請求方式 應該有不一樣的處理邏輯
            # if request.method == 'GET':
            #     print('收到了')
            #     print(request.method)  # 可以獲取前端請求方式 而且是全大寫的字符串
            #     print(type(request.method))
            #     return render(request,'login.html')
            # elif request.method == 'POST':
            #     # 獲取用戶輸入 作相應的邏輯判斷
            #     return HttpResponse("拿到了 老弟")
            if request.method == 'POST':
                return HttpResponse('來啦 寶貝')
            return render(request,'login.html')

# 獲取前端數據

在後端PY 文件中 request.method獲取請求方式: get,  post

對數據的處理 不僅僅只有wsgiref模塊  django後端也進行了大量的數據處理

GET

 

request.GET獲取前端get提交的數據(就相似因而一個大字典)

取值

request.GET.get('username')  # 雖然value是一個列表 可是默認只取列表最後一個元素

# 強烈不建議你使用中括號的形式取值

 

# 若是想直接把列表所有取出(******)

request.GET.getlist('hobby')

POST

request.POST獲取前端post提交的數據(就相似因而一個大字典)

取值

request.POST.get('username')  # 雖然value是一個列表 可是默認只取列表最後一個元素

# 強烈不建議你使用中括號的形式取值

 

# 若是想直接把列表所有取出(******)

request.POST.getlist('hobby')

 

 

## 數據庫配置

 

django默認使用的是自帶的sqlite數據庫  

若是你想讓它其餘的數據庫  須要在settings配置文件中 配置

 

# 1.settings文件中配置
                DATABASES = {
            'default': {
                'ENGINE': 'django.db.backends.mysql',
                'NAME': 'day51',
                'HOST':'127.0.0.1',
                'PORT':3306,
                'USER':'root',
                'PASSWORD':'123',
                'CHARSET':'utf8'
            }
}
# 2.還要在項目名下的init文件或者是應用名下的init文件中告訴django不要使# 用默認的mysqldb鏈接mysql
        # 而是使用pymysql
            import pymysql
            pymysql.install_as_MySQLdb()

## 

django orm

ORM 對象關係映射

表    ----- -----      類

一條條記錄 -----   對象

字段對應的值   ---  對象的屬性

1,模型表的創建過程:

首先須要在應用下的models.py中書寫模型類

 

class User(models.Model):
            # 將id字段設置爲User表主鍵字段  在django orm中 你能夠不寫主鍵字典  django會默認給你的表建立一個名爲id的主鍵字段
            # id = models.AutoField(primary_key=True)  # 一旦你本身指定了主鍵字段 那麼django就不會自動再幫你建立了
            username = models.CharField(max_length=32)  # username varchar(32)   CharField必需要指定max_length參數
            password = models.IntegerField()  # password int
    *************************須要執行數據庫遷移(同步)命令******************************
    python3 manage.py makemigrations  # 僅僅是在小本本上(migrations文件夾)記錄數據庫的修改 並不會直接操做數據
    python3 manage.py migrate  # 將數據庫修改記錄 真正同步到數據庫

注意:只要動了models中跟數據庫相關的代碼 就必須從新執行上面的兩條命令 缺一不可!!!!

###

 

2,表字段的增刪改查

 

 

當一張表已經建立出來以後 後續還想添加字段,能夠有兩種方式

1.給新增的字段設置默認值

addr = models.CharField(max_length=32,default='China')  # default該字段默認值

 

2.給新增的字段設置成能夠爲空

age = models.IntegerField(null=True)  # 該字段容許爲空

2,刪除

刪(慎用)

刪除字段 直接在models.py中註釋該字段 而後從新執行兩條命令便可

python3 manage.py makemigrations  # 僅僅是在小本本上(migrations文件夾)記錄數據庫的修改 並不會直接操做數據
    python3 manage.py migrate  # 將數據庫修改記錄 真正同步到數據庫

注意:執行完以後 表中該字段所對應的全部的數據所有刪除

而且通常狀況下 基本是不會用到真正意義上的刪除

 

3,

orm操做須要使用models中的類的名字

##數據的查
        from app01 import models
        
        models.User.objects.all()  # 直接拿全部的數據
        
        models.User.objects.get(username=username)  
        
        res = models.User.objects.filter(username=username)
        res.query 
        
##數據的增
        1.
        models.User.objects.create(username=username,password=password)
        2.
        user_obj = models.User(username=username,password=password)
        user_obj.save()
    
#
        models.User.objects.filter(條件).delete()
    
#
        models.User.objects.filter(條件).update()
        

 

路由層

url()方法 第一個參數 實際上是一個正則表達式

 

路由匹配 

 

url(正則表達式,視圖函數內存地址)

 

只要正則匹配到了內容,就再也不繼續往下匹配,而是直接後面的視圖函數

 

匹配首頁

 

url(r'^$',home)

 

匹配尾頁

 

url(r'',errors)

 

## 路由匹配的規律

 

第一次按照用戶輸入什麼就匹配什麼若是匹配不上

 

第二次django會讓瀏覽器自動再尾部加斜槓再次匹配 還匹配不上就會報錯

 

上述規律不是瀏覽器的特色,是django的功能

 

django settings文件中

APPEND_SALSH = True  # 自動加斜槓

 

"""爲何setting文件中變量名必須寫全大寫"""

 

一旦前面的正則匹配到了內容 就不會再往下繼續匹配 而是直接執行對應的視圖函數

 

正是因爲上面的特性  當你的項目特別龐大的時候  url的先後順序也是你須要你考慮

 

極有可能會出現url錯亂的狀況

 

 

django在路由的匹配的時候  當你在瀏覽器中沒有敲最後的斜槓

django會先拿着你沒有敲斜槓的結果取匹配 若是都沒有匹配上  會讓瀏覽器在末尾加斜槓再發一次請求 再匹配一次 若是還匹配不上纔會報錯

若是你想取消該機制 不想作二次匹配能夠在settings配置文件中 指定

APPEND_SLASH = False  # 該參數默認是True

 

 

無名分組

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

路由匹配的時候 會將括號內正則表達式匹配到的內容 當作位置參數傳遞給視圖函數

test(request,2019)

 

有名分組

url(r'^test/(?P<year>\d+)/', views.test)

路由匹配的時候 會將括號內正則表達式匹配到的內容 當作關鍵字參數傳遞給視圖函數

test(request,year=2019)

 

# 無名有名不能混合使用 !!!

    url(r'^test/(\d+)/(?P<year>\d+)/', views.test),

 

可是用一種分組下 可使用多個

# 無名分組支持多個

# url(r'^test/(\d+)/(\d+)/', views.test),

# 有名分組支持多個

# url(r'^test/(?P<year>\d+)/(?P<xx>\d+)/', views.test),

 

 

反向解析

本質:其實就是給你返回一個可以返回對應url的地址

 

1.先給url和視圖函數對應關係起別名

url(r'^index/$',views.index,name='kkk')

 

2.反向解析

後端反向解析

後端能夠在任意位置經過reverse反向解析出對應的url

from django.shortcuts import render,HttpResponse,redirect,reverse

reverse('kkk')

 

前端反向解析

{% url 'kkk' %}

 

無名分組反向解析

 

url(r'^index/(\d+)/$',views.index,name='kkk')

 

後端反向解析

reverse('kkk',args=(1,))  # 後面的數字一般都是數據的id值

前端反向解析

{% url 'kkk' 1%}   # 後面的數字一般都是數據的id值

 

 

有名分組反向解析

同無名分組反向解析意義的用法

 

url(r'^index/(?P<year>\d+)/$',views.index,name='kkk')

 

後端方向解析

print(reverse('kkk',args=(1,)))  # 推薦你使用上面這種

print(reverse('kkk',kwargs={'year':1}))

前端反向解析

<a href="{% url 'kkk' 1 %}">1</a>  # 推薦你使用上面這種

<a href="{% url 'kkk' year=1 %}">1</a>

 

例子:

 

 傳參數

 

 

 

注意:在同一個應用下 別名千萬不能重複!!!

 

 

路由分發(******)

當你的django項目特別龐大的時候 路由與視圖函數對應關係特別特別多 

那麼你的總路由urls.py代碼太過冗長  不易維護

 

每個應用均可以有本身的urls.py,static文件夾,templates文件夾(******)

 

正是基於上述條件 能夠實現多人分組開發 等多人開發完成以後  咱們只須要建立一個空的django項目

而後將多人開發的app所有註冊進來 在總路由實現一個路由分發 而再也不作路由匹配(來了以後 我只給你分發到對應的app中)

 

 

當你的應用下的視圖函數特別特別多的時候  你能夠建一個views文件夾 裏面根據功能的細分再建不一樣的py文件

 

 

 urlpatterns = [

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

   url(r'^app01/',include('app01.urls')),

   url(r'^app02/',include('app02.urls')),

 

  ]

 

 

 

 

 

名稱空間(瞭解)

多個app起了相同的別名 這個時候用反向解析 並不會自動識別應用前綴

若是想避免這種問題的發生

方式1:

 

總路由

url(r'^app01/',include('app01.urls',namespace='app01'))

url(r'^app02/',include('app02.urls',namespace='app02'))

 

後端解析的時候

reverse('app01:index')

reverse('app02:index')

前端解析的時候

{% url 'app01:index' %}

{% url 'app02:index' %}

 

方式2:

起別名的時候不要衝突便可  通常狀況下在起別名的時候一般建議以應用名做爲前綴

name = 'app01_index'

name = 'app02_index'

 

 

 

僞靜態

靜態網頁:數據是寫死的 萬年不變

 

僞靜態網頁的設計是爲了增長百度等搜索引擎seo查詢力度

 

全部的搜索引擎其實都是一個巨大的爬蟲程序

 

網站優化相關  經過僞靜態確實能夠提升你的網站被查詢出來的機率

可是再怎麼優化也抵不過RMB玩家

 

 

 

虛擬環境

 

通常狀況下 咱們會給每個項目 配備該項目所須要的模塊 不須要的一律不裝

虛擬環境 就相似於爲每一個項目量身定作的解釋器環境

 

 

如何建立虛擬環境

每建立一個虛擬環境 就相似於你又下載了一個全新的python解釋器

 

 

django版本的區別

django1.X跟django2.X版本區別

路由層1.X用的是url

而2.X用的是path

 

2.X中的path第一個參數再也不是正則表達式,而是寫什麼就匹配什麼 是精準匹配

 

當你使用2.X不習慣的時候  2.X還有一個叫re_path

2.x中的re_path就是你1.X的url

 

 

雖然2.X中path不支持正則表達式  可是它提供了五種默認的轉換器

 

1.0版本的url和2.0版本的re_path分組出來的數據都是字符串類型

默認有五個轉換器,感興趣的本身能夠課下去試一下

str,匹配除了路徑分隔符(/)以外的非空字符串,這是默認的形式

int,匹配正整數,包含0。

slug,匹配字母、數字以及橫槓、下劃線組成的字符串。

uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。

path,匹配任何非空字符串,包含了路徑分隔符(/)(不能用?)

 

 

 

path('index/<int:id>/',index)  # 會將id匹配到的內容自動轉換成整型

 

 

 

還支持自定義轉換器

class FourDigitYearConverter:  

regex = '[0-9]{4}'  

def to_python(self, value):  

return int(value)  

def to_url(self, value):  

return '%04d' % value  佔四位,不夠用0填滿,超了則就按超了的位數來!

register_converter(FourDigitYearConverter, 'yyyy')  

 

urlpatterns = [  

path('articles/2003/', views.special_case_2003),  

path('articles/<yyyy:year>/', views.year_archive),  

...  

]  

 

 

視圖層

1.小白必會三板斧

1.HttpResponse

2.render

3.redirect

django視圖函數必需要給返回一個HttpResponse對象

 

先後端分離

前端一我的幹(前端轉成自定義對象)

JSON.stringify()        json.dumps()

JSON.parse() json.loads()

 

 

後端另外一個幹(python後端用字典)

只要涉及到數據交互,通常狀況下都是用的json格式

後端只負責產生接口,前端調用該接口能拿到一個大字典

後端只須要寫一個接口文檔 裏面描述字典的詳細信息以及參數的傳遞

2.JsonReponse

from django.http import JsonResponse

def index(request):

data = {'name':'jason好帥哦 我好喜歡','password':123}

l = [1,2,3,4,5,6,7,8]

# res = json.dumps(data,ensure_ascii=False)

# return HttpResponse(res)

# return JsonResponse(data,json_dumps_params={'ensure_ascii':False})

return JsonResponse(l,safe=False)  # 若是返回的不是字典 只須要修改safe參數爲false便可

 

3.上傳文件

form表單上傳文件須要注意的事項

1.enctype須要由默認的urlencoded變成formdata

2.method須要由默認的get變成post

(目前還須要考慮的是 提交post請求須要將配置文件中的csrf中間件註釋)

   

  form表單上傳文件

須要注意的實現

1.method必須是post

2.enctype必需要指定成formdata

3.目前須要考慮的 須要將settings配置文件中的csrf中間件註釋掉

後端再也不經過request.POST獲取文件數據,而是經過request.FILES

file_obj = request.FILES.get('myfile')

file_obj.name  # 文件名

with open(file_obj.name,'wb') as f:

for chunk in file_obj.chunks():

f.write(chunk)

 

若是form表單上傳文件 後端須要在request.FILES獲取文件數據 而再也不是POST裏面

 

 

request.method

request.GET

request.POST

request.FILES

request.path  # 只回去url後綴 不獲取?後面的參數

request.get_full_path()  # 後綴和參數所有獲取

相關文章
相關標籤/搜索