Django(三) django生命周期,路由層
orm表關系如何建立
#先導入django中的models模塊
from django.db import models
#先不考慮外鍵關系,創建基表
class Book(models.Model):
titile = models.CharField(max_length = 32) #CharField字段一定要設置max_length
#小數總共八位,小數點后占兩位
price = models.DecimalField(max_digits=8,decimal_places=2)
# to用來指代跟哪張表有關系 默認關聯的就是表的主鍵字段
publish_id = models.ForeignKey(to='Publish')
'''
一對多外鍵字段,同步到數據中心后,表字段會自動加_id后綴
如果手動加上_id,同步之后,還是會自動加上另一個_id
'''
#書和作者是多對多的關系,外鍵字段可以建在任意一方,一般建在查詢頻率高的一方
#django orm會自動創建書籍和作者的第三張關系表
#author該字段是一個虛擬字段,不能在表中展示出來,僅是起到一個高速orm,在建第三張表的關系起到作用
author = models.ManytoManyField(to='Author')
class Publish(models.Model):
title = models.CharField(max_length=32)
email = models.EmailField()
class Author(models.Model):
name = models.CharField(max_length=32)
email = models.EmailField()
#一對一的表關系,外鍵字段建在任意一方都可以,一般建在查詢頻率高的一方
author_detail = models.OneToOneField(to='Author_detail')
class Author_detail(models.Model):
phone = models.BigIntegerField()
addr = models.CharField(max_length=32)
django請求生命周期流程圖

urls.py路由層
url的第一個參數是一個正則表達式,只要是該正則表達式能夠匹配到內容,就會立刻執行后面的視圖韓式,而不再往下繼續匹配了
from django.conf.urls import url
urlpatterns = [
url(正則表達式, views視圖函數,參數,別名),
]
路由匹配
#不加斜杠,會先匹配一次,如果匹配不上,Django可以讓瀏覽器在url后自動加斜杠
#取消該功能
APPEND_SLASH = False # 該參數默認是True
無名分組
#將分組內正則表達式匹配到的內容當做位置參數傳遞給視圖函數
url(r'^test/([0-9]{4})/', views.test)
#當路由中有分組的正則表達式,在匹配到內容,執行視圖函數的時候,會將分組內正則表達式匹配的把內容當做位置參數傳給視圖函數
有名分組
會將分組內的正則表達式匹配到的內容當做關鍵字參數傳遞給視圖函數
#語法
url(r'^testadd/(?P<year>\d+)',views.testadd)
# 當你的路由中有分組並且給分組起了別名 那么在匹配內容的時候
# 會將分組內的正則表達式匹配到的內容當做關鍵字參數傳遞給視圖函數 testadd(request,year=分組內的正則表達式匹配到的內容)
有名分組和無名分組不能混合使用!
反向解析
根據別名,動態解析出一個結果,該結果可以直接訪問對應的url
第一種情況
#路由中沒有正則表達式 直接是寫死的
url(r'^home/', views.home,name='xxx'), # 給路由與視圖函數對應關系起別名
#前端反向解析
{% url 'xxx' %}
#后端反向解析
from django.shortcuts import reverse
url = reverse('xxx')
第二種情況
#無名分組的反向解析 在解析的時候 你需要手動指定正則匹配的內容是什么
url(r'^home/(\d+)/', views.home,name='xxx'), # 給路由與視圖函數對應關系起別名
#前端反向解析
<p><a href="{% url 'xxx' 12 %}">111</a></p>
<p><a href="{% url 'xxx' 1324 %}">111</a></p>
<p><a href="{% url 'xxx' 14324 %}">111</a></p>
<p><a href="{% url 'xxx' 1234 %}">111</a></p>
#后端反向解析
url = reverse('xxx',args=(1,))
url1 = reverse('xxx',args=(3213,))
url2 = reverse('xxx',args=(2132131,))
# 手動傳入的參數 只需要滿足能夠被正則表達式匹配到即可
第三種情況
#有名分組的反向解析 在解析的時候 你需要手動指定正則匹配的內容是什么
#有名分組的反向解析可以跟無名分組一樣
#但是最最正規的寫法
url(r'^home/(?P<year>\d+)/', views.home,name='xxx'), # 給路由與視圖函數對應關系起別名
#前端
# 可以直接用無名分組的情況
<p><a href="{% url 'xxx' 12 %}">111</a></p>
# 你也可以規范寫法
<p><a href="{% url 'xxx' year=1232 %}">111</a></p> # 了解即可
#后端
# 可以直接用無名分組的情況
url = reverse('xxx',args=(1,))
# 你也可以規范寫法
url = reverse('xxx',kwargs={'year':213123})
#以編輯功能為例
url(r'^edit_user/(\d+)/',views.edit_user,name='edit')
def edit_user(request,edit_id):
# edit_id就是用戶想要編輯數據主鍵值
pass
{% for user_obj in user_list %}
<a href='/edit_user/{{user_obj.id}}/'>編輯</a>
<a href='{% url 'edit' user_obj.id %}'>編輯</a>
{% endfor %}
路由分發
路由分發的前因:
在django中所有的app都可以有自己獨立的urls.py templates static
路由分發解決的就是項目的總路由匹配關系過多的情況
使用路由分發,會將總路由不再做匹配的活,而僅僅是做任務分發(請求來了之后,總路由不做對應關系)只詢問你要訪問哪個app的功能 然后將請求轉發給對應的app去處理
urlpatterns = [
url(r'^admin/', admin.site.urls), # url第一個參數是一個正則表達式
# 路由分發
url(r'^app01/',include(app01_urls)), # 路由分發需要注意的實現 就是總路由里面不能以$結尾
url(r'^app02/',include(app02_urls)),
]
# 子路由
from django.conf.urls import url
from app01 import views
urlpatterns = [
url('^reg/',views.reg)
]
from django.conf.urls import url
from app02 import views
urlpatterns = [
url('^reg/',views.reg)
]
#最省事的寫法(******)
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls'))
名稱空間
當多個app中出現了起別名沖突的情況,在做路由分發的時候,可以給每一個app創建一個名稱空間,然后在反向解析的時候,可以選擇到底去哪個名稱空間中查找別名
url(r'^app01/',include('app01.urls',namespace='app01')),
url(r'^app02/',include('app02.urls',namespace='app02'))
# 后端
print(reverse('app01:reg'))
print(reverse('app02:reg'))
# 前端
<a href="{% url 'app01:reg' %}"></a>
<a href="{% url 'app02:reg' %}"></a>
#使用名稱空間會開辟內存資源,占空間
#其實上面的名稱空間知識點可以完全不用,你只需要保證起別名的時候 在整個django項目中不沖突即可
起別名的時候統一加上應用名前綴
urlpatterns = [
url(r'^reg/',views.reg,name='app02_reg')
]
urlpatterns = [
url('^reg/',views.reg,name='app01_reg')
]
偽靜態
將一個動態網頁偽裝成一個靜態網頁 以此來挺好搜索引擎SEO查詢頻率和搜藏力度
所謂的搜索引擎其實就是一個也別巨大的爬蟲程序
url(r'^app01.html',include('app01.urls')),
虛擬環境
給每一個項目 裝備該項目所需要的模塊 不需要的模塊一概不裝
每創建一個虛擬環境就類似於你重新下載了一個純凈python解釋器
之后該項目用到上面 你就裝什么(虛擬環境一台機器上可以有N多個)
django版本區別
urls.py中路由匹配的方法有區別
django2.X用的是path
urlpatterns = [
path('admin/', admin.site.urls),
]
django1.X用的是url
urlpatterns = [
url(r'^reg.html',views.reg,name='app02_reg')
]
# 區別 django2.X里面path第一個參數不是正則也不支持正則 寫什么就匹配什么
# 雖然path不支持正則 感覺也好用 django2.X還有一個re_path的方法 該方法就是你django1.X里面url
# 雖然path支持 但是它提供了五種轉換器 能夠將匹配到的數據自動轉黃成對應的類型
# 除了有默認五種轉換器之外 還支持你自定義轉換器
涉及知識點梳理
mysql數據庫之表與表之間的關系
一對多
foreign key
外鍵約束
1. 在創建表的時候,必須先創建被關聯表
2. 插入數據的時候,也必須先插入被關聯表的數據
如員工表和部門表之間就是一對多的關系,通常將關鍵字段稱之為外鍵字段
外鍵建在多的一方
多對多
以圖書表和作者表舉例(換位思考)
1. 先站在圖書表:多本書能否是一個作者
2. 站在作者表中:多個作者能否共同編寫一本書
如果雙方都成立,那么就是多對多
多對多關系的建立,必須手動創建第三張表,專門用來記錄兩種表之間的關系
一對一
一對一關系對較少,一般當表特別龐大時,可以拆分表
比如客戶信息,與詳細信息表
外鍵字段可以建在任意一方,一般建在查詢頻率高的一方
re模塊(正則表達式)
re模塊:去字符串找符合某種特點的字符串
import re
s = 'abcdabc'
#^ :以...開頭
res = re.findall('^ab',s)
#$ :以...結尾
res = re.findall('bc$',s)
# . :任意字符
res = re.findall('abc',s)
# \d :數字
res = re.findall('\d',s)
# \w :非空,數字字母下划線
res = re.findall('\w',s)
# \s :空,空格
res = re.findall('\s',s)
# \D:非數字
res = re.findall('\D',s)
# \W:空
res = re.findall('\W',s)
#\S :非空
res = re.findall('\S',s)
# + :前面的一個字符至少一個
print(re.findall('abc+',s))
# ? :尋找到?前面的一個字符 0-1 個
print(re.findall('abcdd?', s))
# * :前面的一個字符至少0個
print(re.findall('abcd*',s))
# [] :中括號內的都可以
print(re.findall('[abc]bc',s))
# [^] :中括號內的都不可以
print(re.findall('[^abc]bc',s))
# | : 或
print(re.findall('abc|bbc',s))
# {2}:前面的字符 2個
print(re,findall('abc{2}',s))
# {1,2} :前面的字符 2 個
print(re,findall('abc{1,2}',s))
#貪婪模式
# .(任意字符) * (0-無窮個)
print(re.findall('a.*g',s))
#非貪婪模式
# . (任意字符) * (0-無窮個)
print(re,findall('a.*?g',s))
#bug # . (任意字符) * (0-無窮個)
print(re.findall('.*?',s))
