1. 程式人生 > >Django的基本使用(五)

Django的基本使用(五)

一、url傳遞引數

1.非關鍵字引數

url地址訪問格式: /路徑/路徑/引數 urls正則的定義: /路徑/路徑/(引數匹配的正則)

注意:

  1. 如果要獲取傳遞進來的引數,必須給對應的引數的正則加上 ()才可以提取,
  2. 如果url中引數引數,就必須在檢視函式的形式引數上定義一個引數,用來接收,否則報錯

如果需要傳遞多個引數: urls正則的定義: /路徑/路徑/(引數匹配的正則)/(引數匹配的正則n) 注意:

  1. 接收的時候,也要定義多個形式引數用來接收url傳遞的引數
  2. 接收的引數 必須 與傳遞的引數一一對應

2.關鍵字引數

urls正則的定義: /路徑/路徑/(?P<別名>引數匹配的正則)/(?P<別名n>引數匹配的正則n)

檢視函式中接收 (request,別名n,別名) 注意: 形式名必須與別名對應 好處: 會自動的用關鍵字傳遞引數, 檢視函式的形參就不需要一一對應了

二、模板中訪問地址及傳遞引數

1.模板中使用連線

1.直接完整的url地址

<a href="https://www.baidu.com/">百度</a>

2.使用相對路徑

<a href="../relation">相對路徑</a>

3.相對於主機的路徑 ip:埠/路徑

<a href="/day05/relation">相對路徑</a>

2.問題: 開發: 開發, 測試, Beta, 正式…

開發的時候,url地址的路徑可能會修改,修改後,在對應模板中的url地址都要進行修改,而實際開發中,一個url可能會被多處使用,修改起來工作量大,且容易出錯

3.解決: url反向解析法

使用: 1.在專案下的url中新增 namespace屬性值作為標識

如:  url(r"^axfxxxx/",include("day05.urls",namespace="day05")),
格式:    url(r"^任意的路徑名/",include("應用的urls位置",namespace="父標識名")), 

2.在應用的url中新增 name 屬性作為標識

如: url(r'relationxxx/', views.relation,name="relation"),
格式 :  url(r'任意的路徑名/', views.函式名,name="子標識名"),

3.在模板使用:

如:  <a href="{%  url 'day05:relation' %}">相對路徑</a>
格式: <a href="{%  url '父標識名:子標識名' %}">相對路徑</a>

4.反向解析—非關鍵字引數

如: <a href="{% url 'day05:urlParam' 2018 9 30 %}">反向解析攜帶引數測試</a>
url: url(r'urlParam/(\d+)/(\d+)/(\d)', views.urlParam,name="urlParam"),
格式:   <a href="{% url '父標識名:子標識名' 引數1 引數2 引數n %}">  每個引數之間用空格隔開即可

5.反向解析 ----關鍵字引數

如: <a href="{% url 'day05:urlParam2' month=9 day=30 year=2019%}">反向解析攜帶引數測試-關鍵字</a>
url:   url(r'urlParam2/(?P<!-- <year> -->\d+)/(?P<!-- <month> -->\d+)/(?P<!-- <day> -->\d+)', views.urlParam2,name="urlParam2"),
格式:  <a href="{% url 'day05:urlParam2' key1=value key2=value keyN=value %}">反向解析攜帶引數測試-關鍵字</a>

關鍵引數是 key=value的形式,key要與url中的別名對應, 每組引數用空格隔開

三、重定向

——給使用者的請求,換一個地址

0.HttpResponseRedirect 的簡寫形式是 redirect

1普通用法:

如: return HttpResponseRedirect("/day05/redirectRes")
格式:  return HttpResponseRedirect("重定向的路徑")

2.反向解析法

1.不攜帶引數

如: return HttpResponseRedirect(reverse("day05:redirectRes"))
    return HttpResponseRedirect(reverse("父標識:子標識"))

2.攜帶非關鍵字引數

如:  return HttpResponseRedirect(reverse("day05:redirectRes2",args=(2019,10,30)))
格式:  return HttpResponseRedirect(reverse("day05:redirectRes2",args=(value1,value2,valueN)))

3.攜帶關鍵字引數

return HttpResponseRedirect(reverse("day05:redirectRes3",kwargs={"year":2020,"month":10,"day":10}))
格式:  return HttpResponseRedirect(reverse("day05:redirectRes3",kwargs={"key1":value1,"keyN":valueN))

四、response 響應體

— 響應該客戶端的資料

1.HttpResponse("字串形式的資料") 直接返回資料給客戶端
2.render(request,"模板檔案路徑",context=引數) 將引數隱射到模板中,轉換成html形式的字串返回給客戶端
3.HttpResponseRedirect("url地址"或者reverse(反向解析)) 重定向, 將該請求轉為其他的處理方式
4.JsonResponse(data) 將data轉換成json格式的資料響應給客戶端,

1.通常是將字典形式的資料轉換成json

strJson = {'name':'張三','age':23}
# 需要字典形式的資料
return JsonResponse(strJson)

2.將model資料轉換成Json資料

    persons = Person.objects.all().values()

    # 將queryset轉換成列表
    persons = list(persons[:])
    #將列表轉成JsonArray資料
    strData = json.dumps(persons)

    return  HttpResponse(strData)

五、request 請求體

瀏覽器會自動的將請求 引數 封裝成一個請求體,傳遞給伺服器 一般只會檢視引數,不能修改引數

1.伺服器會自動的將request傳遞給檢視函式

2.request 重要的屬性

  request.path  獲取請求的路徑
  request.method  獲得請求的方式   GET 和 POST
 
  request.FILES  獲取檔案資料
  request.cookie
  request.session

  request.GET 攜帶客戶端get請求的引數
  request.POST 攜帶客戶post請求的引數

3.get請求

1.request.GET中就包含了get請求的引數, request.GET是類似字典形式的資料 2.獲取資料

  1. request.GET[“引數名”] 可以獲取引數名對應的資料,如果引數名不存在,會報錯
  2. request.GET.get(“引數名”,預設值) 可以獲取引數名對應的資料,如果引數名不存在,不會報錯,會使用預設值, 如果設定預設值,預設值為None
  3. request.GET.getList(“引數名”) 可以獲取引數名對應的資料,如果是一個引數名對應多個數據,就可以使用getlist來獲取,結果是list形式

4.post請求

1.request.POST中就包含了post請求的引數, request.POST是類似字典形式的資料 2.獲取引數的用法與GET一致 3.注意: 在django的post請求中自帶csrf驗證,所有普通方式不能直接訪問,伺服器會拒絕訪問 解決:

  1. 直接在表單中的首行 加上 {% csrf_token %} 即可, 表示加上csrf認證
  2. 去掉django的csrf認證 在setting的MIDDLEWARE中將'django.middleware.csrf.CsrfViewMiddleware', 登出即可

六、model的繼承及問題

0.資料庫優化問題

1.儘量避免表關聯 — 資料操作效率低 2.儘量的避免io

1.問題

在django中,model可以使用繼承即子類可以繼承父類, 預設情況下,繼承之後,使用遷移建立資料庫表之後,預設會建立一個父類表,也會建立子類表, 但是子類表中的繼承的屬性,不會在子類表中,而是通過外來鍵關聯父類表獲得。預設情況不合理,應該子類是一個獨立的表,避免表關聯

2.解決

將父類model定義成抽象的類即可 如: 在父model中新增

class Meta:
    abstract  = True

使得model抽象華.不能例項化, 繼承的子模型就不會再關聯父表,子模型會是獨立的表,且會繼承父類的模型的屬性,

3.遷移問題

遷移的時候,可能會因為遷移檔案已經有對應的記錄,而使得遷移失敗

解決

  1. 刪除對應的表(小心)
  2. 在django-migrations表中刪除對應的記錄
  3. 刪除migrations目錄下的遷移檔案
  4. 再次重新遷移即可