django請求週期流程, url的無名分組與有名分組, 反向解析, 路由分發, 僞靜態, 虛擬環境

[TOC]html

django創建表關係

一對一的表間關係應用場景

QQ: 基本經常使用展現信息<==>更多信息, 節省數據查詢時間前端

一對一關係的兩張表能夠拼成一張表, 反之一張表也能拆成兩張一對一的表python

外鍵設定在一對多中多的一方, 建立表時必須先建立沒有外鍵約束的表git

多對多的外鍵設定在關係表中正則表達式

建立表關係

# 先創基表再考慮外鍵關係
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)

    publish = models.ForeignKey(to='Publish')  # 創建出版社與書的一對多關係, 默認關聯主鍵字段

    """
    1. 創建書與做者的多對多關係, 建議外鍵建在查詢頻率高的一方
    2. django orm會自動建立二者之間的關係表
    3. author字段是一個虛擬字段, 不會在表中展現
    """
    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)
    age = models.IntegerField()

    # 創建做者與做者詳情的一對一關係, 建議外鍵建在查詢頻率高的一方
    author_detail = models.OneToOneField(to='AuthorDetails')
    # author_detail = models.ForeignKey(to='AuthorDetails', db_constraint='unique')  # fk + unique


class AuthorDetails(models.Model):
    phone = models.BigIntegerField()
    address = models.CharField(max_length=32)

# 外鍵字段同步到數據庫中會自動加"_id"

django請求週期流程圖

無名分組和有名分組

無名分組

  • url(r'^test/([0-9]{4})/', views.test)
  1. 報錯: test() takes 1 positional argument but 2 were given
  2. 當url中的正則表達式包含無名分組時, 會將無名分組內的正則表達式匹配到的內容當作位置參數傳遞給視圖函數
  3. test(request, x)

有名分組

  • url(r'^test_add/(?P<y>\d+)/', views.test_add)
  1. 當url中的正則表達式包含有名分組時, 會將有名分組內的正則表達式匹配到的內容當作關鍵字參數傳遞給視圖函數
  2. test_add(request, y)

補充

  1. 利用有名分組和無名分組, 就能夠在調用視圖函數以前給函數傳遞額外的參數
  2. url(r'^index/(\d+)/(?P<y>\d+)/', views.index), 報錯
  3. 同一種分組有多個, 可是不能混合使用, url(r'^index/(\d+)/(\d+)/', views.index)

路由匹配

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'test/', views.test),
    url(r'test_add/', views.test_add),
]

"""
1. url第一個參數是一個正則表達式, 
2. 會與處理獲得的前端url路徑後綴字符串進行匹配,
3. 一旦匹配到內容, 會馬上結束匹配關係, 執行第二個參數對應的函數
"""

1.django匹配路由的規律:數據庫

  • 先對前端url路徑後綴字符串匹配一次試試 , 若是隻是沒有匹配到斜槓,
  • 會讓瀏覽器重定向, 在路徑後綴中加一個斜槓再發送一次, 若是還匹配不上, 纔會報錯

2.取消django自動讓瀏覽器加斜槓的功能: settings-->APPEND_SLASH = Falsedjango

3.url(r'^test/$', views.test), 限制後綴名只能輸入test/, $視狀況添加後端

4.路由匹配只匹配url部分, 不匹配?後面get請求攜帶的參數瀏覽器

反向解析

什麼是反向解析

根據一個別名, 動態解析出一個結果,app

該結果能夠直接訪問對應的url,

多<==>一<==>一

狀況一: 路由中沒有正則表達式

url(r'^home/', views.home,name='xxx'), 多: 動態變化的url; 一: xxx;

前端反向解析: <a href="{% url 'xxx' %}">111</a>

後端反向解析:

def get_url(request):
    url = reverse('xxx')
    print(url)
    return redirect(url)

狀況二: 無名分組的反向解析

訪問/index/, 報錯: Reverse for 'xxx' with no arguments not found. 1 pattern(s) tried: ['home/(\d+)/']

前端反向解析: <a href="{% url 'xxx' 1 %}">111</a>,

在解析的時候, 須要指定無名分組內的正則匹配表達式匹配的內容

後端反向解析: reverse('xxx', args=(1, ))

urlpatterns = [
    url(r'^index/', views.index),
    url(r'^home/(\d+)/', views.home, name='xxx'),
    url(r'^get_url/', views.get_url),
]


def index(request):
    return render(request, 'index.html')


# <p><a href="{% url 'xxx' 1 %}">111</a></p>  # 數字一般是數據的主鍵值


def home(request, x):
    return HttpResponse([x, 'home'])


def get_url(request):
    url = reverse('xxx', args=(1, ))
    print(url)
    return redirect(url)

狀況三: 有名分組的反向解析

前端反向解析: <a href="{% url 'xxx' yyy=1 %}">111</a>,

在解析的時候, 須要指定有名分組內的正則匹配表達式匹配的內容

後端反向解析: url = reverse('xxx', kwargs={'yyy': 1})

應用場景: 編輯功能

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
  • 所以, 用django開發項目, 就可以徹底作到多人分組開發, 互相不干擾
  • 最後利用路由分發將多個app整合到一塊兒便可完成一個大項目的拼接

總路由

from django.conf.urls import url, include

from app01 import urls as app01_urls
from app02 import urls as app02_urls

urlpatterns = [
    url(r'^app01/', include(app01_urls)),  # 注意: 總路由裏面不能以$結尾
    url(r'^app02/', include(app02_urls),)
]

# 精簡寫法, 不須要導入, url(r'^app01/', include('app01.urls')),

子路由

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

urlpatterns = [
    url('^reg/', views.reg)
]

名稱空間

爲何要有名稱空間

  • 當多個app中出現了起別名衝突的狀況, 在作路由分發的時候, 能夠給每個app建立一個名稱空間
  • 而後在反向解析的時候, 能夠選擇到底去哪一個名稱空間中查找別名

前端: <a href="{% url 'app01:reg' %}"></a>

後端: reverse('x:reg')

# 總路由
urlpatterns = [
    url(r'^app01/', include('app01.urls', namespace='x')),
    url(r'^app02/', include('app02.urls', namespace='y')),
]

# 兩個子路由
urlpatterns = [
    url('^reg/', views.reg, name='reg')
]


# 視圖函數
def reg(request):
    url = reverse('x:reg')
    print(url)
    return HttpResponse('app01 reg')

補充

  • 其實只須要保證起別名的時候 在整個django項目中不衝突,
  • 建議起別名的時候統一加上應用名前綴: url('^reg/', views.reg, name='app01_reg')

僞靜態

  • 將一個動態網頁假裝成一個靜態網頁 以此來增長搜索引擎SEO查詢頻率和收藏力度
  • 搜索引擎其實就是一個特別巨大的爬蟲程序

虛擬環境

爲何要有虛擬環境

  • 給每個項目, 裝備該項目所須要的模塊, 不須要的模塊一律不裝

建立虛擬環境

  • 每建立一個虛擬環境就相似於從新下載了一個純淨python解釋器
  • Inherit global site-packages, 不繼承全局的包
  • Make available to all projects, 建立的虛擬環境可供任何項目使用

django版本區別

django1.X和django2.X

  • urls.py中路由匹配的方法有區別
  • django1.X用的是url, django2.X用的是path
  • django2.X裏面path第一個參數不是正則也不支持正則 寫什麼就匹配什麼
  • django2.X還有一個re_path的方法, 該方法至關於django1.X裏面的url
  • path提供了五種轉換器, 可以將匹配到的數據自動轉換成對應的類型, 還支持自定義轉換器

python後端獲取文件對象

form表單上傳文件注意事項

  1. method必須改爲post
  2. enctype該成multipart/form-data格式
  3. 在使用post朝後端發請求的時候, 須要去settings配置文件中註釋掉一箇中間件csrf
<form action="" method="post" enctype="multipart/form-data">
    <input type="file" name="my_file">
    <input type="submit">
</form>
def upload_file(request):
    if request.method == 'POST':
        print(request.FILES)  # <MultiValueDict: {'my_file': [<TemporaryUploadedFile: test.pdf (application/pdf)>]}>
        file_obj = request.FILES.get('my_file')  # 獲取列表中最後一個元素
        print(file_obj)  # test.pdf, __str__控制打印值
        print(file_obj.name)  # test.pdf

        with open(file_obj.name, 'wb') as fw:
            for line in file_obj:
                fw.write(line)

    return render(request, 'upload.html')
相關文章
相關標籤/搜索