一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Django~1

 Alairi70ikx79r 2018-01-10

一 什么是web框架?

框架,即framework,特指為解決一個開放性問題而設計的具有一定約束性的支撐結(jié)構(gòu),使用框架可以幫你快速開發(fā)特定的系統(tǒng),簡單地說,就是你用別人搭建好的舞臺來做表演。

對于所有的Web應用,本質(zhì)上其實就是一個socket服務端,用戶的瀏覽器其實就是一個socket客戶端。

復制代碼
import socket

def handle_request(client):

    buf = client.recv(1024)
    client.send("HTTP/1.1 200 OK\r\n\r\n".encode("utf8"))
    client.send("<h1 style='color:red'>Hello, yuan</h1>".encode("utf8"))

def main():

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost',8001))
    sock.listen(5)

    while True:
        connection, address = sock.accept()
        handle_request(connection)
        connection.close()

if __name__ == '__main__':

    main()
復制代碼

      最簡單的Web應用就是先把HTML用文件保存好,用一個現(xiàn)成的HTTP服務器軟件,接收用戶請求,從文件中讀取HTML,返回。

如果要動態(tài)生成HTML,就需要把上述步驟自己來實現(xiàn)。不過,接受HTTP請求、解析HTTP請求、發(fā)送HTTP響應都是苦力活,如果我們自己來寫這些底層代碼,還沒開始寫動態(tài)HTML呢,就得花個把月去讀HTTP規(guī)范。

      正確的做法是底層代碼由專門的服務器軟件實現(xiàn),我們用Python專注于生成HTML文檔。因為我們不希望接觸到TCP連接、HTTP原始請求和響應格式,所以,需要一個統(tǒng)一的接口,讓我們專心用Python編寫Web業(yè)務。

這個接口就是WSGI:Web Server Gateway Interface。

-----------------------------Do a web  framework ourselves---------------------------

step 1:

View Code

注意:

View Code

step 2

View Code

step3

View Code

step4

View Code

伙計們,不知不覺我們自己已經(jīng)寫出一個web框架啦!

二 MVC和MTV模式

著名的MVC模式:所謂MVC就是把web應用分為模型(M),控制器(C),視圖(V)三層;他們之間以一種插件似的,松耦合的方式連接在一起。

模型負責業(yè)務對象與數(shù)據(jù)庫的對象(ORM),視圖負責與用戶的交互(頁面),控制器(C)接受用戶的輸入調(diào)用模型和視圖完成用戶的請求。

                  

Django的MTV模式本質(zhì)上與MVC模式?jīng)]有什么差別,也是各組件之間為了保持松耦合關(guān)系,只是定義上有些許不同,Django的MTV分別代表:

       Model(模型):負責業(yè)務對象與數(shù)據(jù)庫的對象(ORM)

       Template(模版):負責如何把頁面展示給用戶

       View(視圖):負責業(yè)務邏輯,并在適當?shù)臅r候調(diào)用Model和Template

       此外,Django還有一個url分發(fā)器,它的作用是將一個個URL的頁面請求分發(fā)給不同的view處理,view再調(diào)用相應的Model和Template

 三 django的流程和命令行工具

django實現(xiàn)流程

View Code

django的命令行工具

django-admin.py 是Django的一個用于管理任務的命令行工具,manage.py是對django-admin.py的簡單包裝,每一個Django Project里都會有一個mannage.py。

<1> 創(chuàng)建一個django工程 : django-admin.py startproject mysite

        當前目錄下會生成mysite的工程,目錄結(jié)構(gòu)如下:

       

  • manage.py ----- Django項目里面的工具,通過它可以調(diào)用django shell和數(shù)據(jù)庫等。
  • settings.py ---- 包含了項目的默認設置,包括數(shù)據(jù)庫信息,調(diào)試標志以及其他一些工作的變量。
  • urls.py ----- 負責把URL模式映射到應用程序。

<2>在mysite目錄下創(chuàng)建blog應用: python manage.py startapp blog

       

<3>啟動django項目:python manage.py runserver 8080

       這樣我們的django就啟動起來了!當我們訪問:http://127.0.0.1:8080/時就可以看到:

       

<4>生成同步數(shù)據(jù)庫的腳本:python manage.py makemigrations  

                     同步數(shù)據(jù)庫:  python manage.py migrate   

       注意:在開發(fā)過程中,數(shù)據(jù)庫同步誤操作之后,難免會遇到后面不能同步成功的情況,解決這個問題的一個簡單粗暴方法是把migrations目錄下

                的腳本(除__init__.py之外)全部刪掉,再把數(shù)據(jù)庫刪掉之后創(chuàng)建一個新的數(shù)據(jù)庫,數(shù)據(jù)庫同步操作再重新做一遍。            

<5>當我們訪問http://127.0.0.1:8080/admin/時,會出現(xiàn):

       

       所以我們需要為進入這個項目的后臺創(chuàng)建超級管理員:python manage.py createsuperuser,設置好用戶名和密碼后便可登錄啦!

<6>清空數(shù)據(jù)庫:python manage.py  flush

<7>查詢某個命令的詳細信息: django-admin.py  help  startapp

       admin 是Django 自帶的一個后臺數(shù)據(jù)庫管理系統(tǒng)。

<8>啟動交互界面 :python manage.py  shell

     這個命令和直接運行 python 進入 shell 的區(qū)別是:你可以在這個 shell 里面調(diào)用當前項目的 models.py 中的 API,對于操作數(shù)據(jù),還有一些小測試非常方便。

<9> 終端上輸入python manage.py 可以看到詳細的列表,在忘記子名稱的時候特別有用

實例練習1-提交數(shù)據(jù)并展示

View Code

實例練習2-提交數(shù)據(jù)并展示(數(shù)據(jù)庫)

View Code

四 Django的配置文件(settings)

靜態(tài)文件設置:

View Code

其它重要參數(shù)設置:

復制代碼
APPEND_SLASH
       Default: True
       When set to True, if the request URL does not match any of the patterns in the URLconf and it 
doesn’t end in a slash, an HTTP redirect is issued to the same URL with a slash appended. Note
that the redirect may cause any data submitted in a POST request to be lost.
復制代碼

五 Django URL (路由系統(tǒng))

     URL配置(URLconf)就像Django 所支撐網(wǎng)站的目錄。它的本質(zhì)是URL模式以及要為該URL模式調(diào)用的視圖函數(shù)之間的映射表;你就是以這種方式告訴Django,對于這個URL調(diào)用這段代碼,對于那個URL調(diào)用那段代碼。

1
2
3
urlpatterns = [
    url(正則表達式, views視圖函數(shù),參數(shù),別名),
]

參數(shù)說明:

  • 一個正則表達式字符串
  • 一個可調(diào)用對象,通常為一個視圖函數(shù)或一個指定視圖函數(shù)路徑的字符串
  • 可選的要傳遞給視圖函數(shù)的默認參數(shù)(字典形式)
  • 一個可選的name參數(shù)

5.1 Here’s a sample URLconf:

復制代碼
from django.conf.urls import url
from django.contrib import admin

from app01 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})/$', views.year_archive),  #no_named group

    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),

]
復制代碼

Note:

View Code

5.2 Named groups

      The above example used simple, non-named regular-expression groups (via parenthesis) to capture bits of the URL and pass them as positional arguments to a view. In more advanced usage, it’s possible to use named regular-expression groups to capture URL bits and pass them as keyword arguments to a view.

       In Python regular expressions, the syntax for named regular-expression groups is (?P<name>pattern), where name is the name of the group and pattern is some pattern to match.

Here’s the above example URLconf, rewritten to use named groups:

ready
復制代碼
from django.conf.urls import url
  
from . import views
  
urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]
復制代碼

       This accomplishes exactly the same thing as the previous example, with one subtle difference: The captured values are passed to view functions as keyword arguments rather than positional arguments.

5.3  Passing extra options to view functions

       URLconfs have a hook that lets you pass extra arguments to your view functions, as a Python dictionary.

The django.conf.urls.url() function can take an optional third argument which should be a dictionary of extra keyword arguments to pass to the view function.

For example:

from django.conf.urls import url
from . import views
  
urlpatterns = [
    url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]

       In this example, for a request to /blog/2005/, Django will call views.year_archive(request, year='2005',foo='bar').

This technique is used in the syndication framework to pass metadata and options to views.

Dealing with conflicts

       It’s possible to have a URL pattern which captures named keyword arguments, and also passes arguments with the same names in its dictionary of extra arguments. When this happens, the arguments in the dictionary will be used instead of the arguments captured in the URL.

5.4 name param

View Code

5.5 Including other URLconfs

復制代碼
#At any point, your urlpatterns can “include” other URLconf modules. This
#essentially “roots” a set of URLs below other ones.

#For example, here’s an excerpt of the URLconf for the Django website itself.
#It includes a number of other URLconfs:


from django.conf.urls import include, url

urlpatterns = [
   url(r'^admin/', admin.site.urls),
   url(r'^blog/', include('blog.urls')),
]
復制代碼

六 Django Views(視圖函數(shù))

http請求中產(chǎn)生兩個核心對象:

        http請求:HttpRequest對象

        http響應:HttpResponse對象

所在位置:django.http

之前我們用到的參數(shù)request就是HttpRequest    檢測方法:isinstance(request,HttpRequest)

1 HttpRequest對象的屬性和方法:

View Code

注意一個常用方法:request.POST.getlist('')

2 HttpResponse對象:

  對于HttpRequest對象來說,是由django自動創(chuàng)建的,但是,HttpResponse對象就必須我們自己創(chuàng)建。每個view請求處理方法必須返回一個HttpResponse對象。

  HttpResponse類在django.http.HttpResponse

  在HttpResponse對象上擴展的常用方法:

1
2
3
頁面渲染:         render()(推薦)<br>                 render_to_response(),
頁面跳轉(zhuǎn):         redirect("路徑")
locals():    可以直接將函數(shù)中所有的變量傳給模板

補充:

View Code

七 Template基礎 

模板系統(tǒng)的介紹

你可能已經(jīng)注意到我們在例子視圖中返回文本的方式有點特別。 也就是說,HTML被直接硬編碼在 Python代碼之中。

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

盡管這種技術(shù)便于解釋視圖是如何工作的,但直接將HTML硬編碼到你的視圖里卻并不是一個好主意。 讓我們來看一下為什么:

  • 對頁面設計進行的任何改變都必須對 Python 代碼進行相應的修改。 站點設計的修改往往比底層 Python 代碼的修改要頻繁得多,因此如果可以在不進行 Python 代碼修改的情況下變更設計,那將會方便得多。

  • Python 代碼編寫和 HTML 設計是兩項不同的工作,大多數(shù)專業(yè)的網(wǎng)站開發(fā)環(huán)境都將他們分配給不同的人員(甚至不同部門)來完成。 設計者和HTML/CSS的編碼人員不應該被要求去編輯Python的代碼來完成他們的工作。

  • 程序員編寫 Python代碼和設計人員制作模板兩項工作同時進行的效率是最高的,遠勝于讓一個人等待另一個人完成對某個既包含 Python又包含 HTML 的文件的編輯工作。

基于這些原因,將頁面的設計和Python的代碼分離開會更干凈簡潔更容易維護。 我們可以使用 Django的 模板系統(tǒng) (Template System)來實現(xiàn)這種模式,這就是本章要具體討論的問題。

------------------------------------------------------------------模板語法------------------------------------------------------------------

一模版的組成

組成:HTML代碼+邏輯控制代碼

二 邏輯控制代碼的組成

1  變量(使用雙大括號來引用變量):

1
語法格式:       {{var_name}}

------Template和Context對象

View Code

 Django 模板解析非??旖荨?大部分的解析工作都是在后臺通過對簡短正則表達式一次性調(diào)用來完成。 這和基于 XML 的模板引擎形成鮮明對比,那些引擎承擔了 XML 解析器的開銷,且往往比 Django 模板渲染引擎要慢上幾個數(shù)量級。

推薦方式

------深度變量的查找(萬能的句點號)

在到目前為止的例子中,我們通過 context 傳遞的簡單參數(shù)值主要是字符串,然而,模板系統(tǒng)能夠非常簡潔地處理更加復雜的數(shù)據(jù)結(jié)構(gòu),例如list、dictionary和自定義的對象。

在 Django 模板中遍歷復雜數(shù)據(jù)結(jié)構(gòu)的關(guān)鍵是句點字符 (.)。

View Code

------變量的過濾器(filter)的使用

1
語法格式:      {{obj|filter:param}}
View Code

2 標簽(tag)的使用(使用大括號和百分比的組合來表示使用tag)

1
{% tags %}

------{% if %} 的使用 

{% if %}標簽計算一個變量值,如果是“true”,即它存在、不為空并且不是false的boolean值,系統(tǒng)則會顯示{% if %}和{% endif %}間的所有內(nèi)容

View Code

------{% for %}的使用

{% for %}標簽允許你按順序遍歷一個序列中的各個元素,每次循環(huán)模板系統(tǒng)都會渲染{% for %}和{% endfor %}之間的所有內(nèi)容

View Code

------{%csrf_token%}:csrf_token標簽

     用于生成csrf_token的標簽,用于防治跨站攻擊驗證。注意如果你在view的index里用的是render_to_response方法,不會生效

     其實,這里是會生成一個input標簽,和其他表單標簽一起提交給后臺的。

------{% url %}:  引用路由配置的地址

View Code

------{% with %}:用更簡單的變量名替代復雜的變量名

1
{% with total=fhjsaldfhjsdfhlasdfhljsdal %} {{ total }} {% endwith %}

------{% verbatim %}: 禁止render

1
2
3
{% verbatim %}
         {{ hello }}
{% endverbatim %}

------{% load %}: 加載標簽庫

3 自定義filter和simple_tag

------a、在app中創(chuàng)建templatetags模塊(必須的)

------b、創(chuàng)建任意 .py 文件,如:my_tags.py

View Code

------c、在使用自定義simple_tag和filter的html文件中導入之前創(chuàng)建的 my_tags.py :{% load my_tags %}

------d、使用simple_tag和filter(如何調(diào)用)

View Code

------e、在settings中的INSTALLED_APPS配置當前app,不然django無法找到自定義的simple_tag.

注意:

filter可以用在if等語句后,simple_tag不可以

View Code

4 extend模板繼承

------include 模板標簽

在講解了模板加載機制之后,我們再介紹一個利用該機制的內(nèi)建模板標簽: {% include %} 。該標簽允許在(模板中)包含其它的模板的內(nèi)容。 標簽的參數(shù)是所要包含的模板名稱,可以是一個變量,也可以是用單/雙引號硬編碼的字符串。 每當在多個模板中出現(xiàn)相同的代碼時,就應該考慮是否要使用 {% include %} 來減少重復。

------extend(繼承)模板標簽

到目前為止,我們的模板范例都只是些零星的 HTML 片段,但在實際應用中,你將用 Django 模板系統(tǒng)來創(chuàng)建整個 HTML 頁面。 這就帶來一個常見的 Web 開發(fā)問題: 在整個網(wǎng)站中,如何減少共用頁面區(qū)域(比如站點導航)所引起的重復和冗余代碼?

解決該問題的傳統(tǒng)做法是使用 服務器端的 includes ,你可以在 HTML 頁面中使用該指令將一個網(wǎng)頁嵌入到另一個中。 事實上, Django 通過剛才講述的 {% include %} 支持了這種方法。 但是用 Django 解決此類問題的首選方法是使用更加優(yōu)雅的策略—— 模板繼承 。

本質(zhì)上來說,模板繼承就是先構(gòu)造一個基礎框架模板,而后在其子模板中對它所包含站點公用部分和定義塊進行重載。

讓我們通過修改 current_datetime.html 文件,為 current_datetime 創(chuàng)建一個更加完整的模板來體會一下這種做法:

View Code

這看起來很棒,但如果我們要為 hours_ahead 視圖創(chuàng)建另一個模板會發(fā)生什么事情呢?

View Code

很明顯,我們剛才重復了大量的 HTML 代碼。 想象一下,如果有一個更典型的網(wǎng)站,它有導航條、樣式表,可能還有一些 JavaScript 代碼,事情必將以向每個模板填充各種冗余的 HTML 而告終。

解決這個問題的服務器端 include 方案是找出兩個模板中的共同部分,將其保存為不同的模板片段,然后在每個模板中進行 include。 也許你會把模板頭部的一些代碼保存為 header.html 文件:

View Code

你可能會把底部保存到文件 footer.html :

View Code

對基于 include 的策略,頭部和底部的包含很簡單。 麻煩的是中間部分。 在此范例中,每個頁面都有一個<h1>My helpful timestamp site</h1> 標題,但是這個標題不能放在 header.html 中,因為每個頁面的 <title> 是不同的。 如果我們將 <h1> 包含在頭部,我們就不得不包含 <title> ,但這樣又不允許在每個頁面對它進行定制。 何去何從呢?

Django 的模板繼承系統(tǒng)解決了這些問題。 你可以將其視為服務器端 include 的逆向思維版本。 你可以對那些不同 的代碼段進行定義,而不是 共同 代碼段。

第一步是定義 基礎模板,該框架之后將由子模板所繼承。 以下是我們目前所講述范例的基礎模板:

View Code

這個叫做 base.html 的模板定義了一個簡單的 HTML 框架文檔,我們將在本站點的所有頁面中使用。 子模板的作用就是重載、添加或保留那些塊的內(nèi)容。 (如果你一直按順序?qū)W習到這里,保存這個文件到你的template目錄下,命名為 base.html .)

我們使用模板標簽: {% block %} 。 所有的 {% block %} 標簽告訴模板引擎,子模板可以重載這些部分。 每個{% block %}標簽所要做的是告訴模板引擎,該模板下的這一塊內(nèi)容將有可能被子模板覆蓋。

現(xiàn)在我們已經(jīng)有了一個基本模板,我們可以修改 current_datetime.html 模板來 使用它:

View Code

再為 hours_ahead 視圖創(chuàng)建一個模板,看起來是這樣的:

View Code

看起來很漂亮是不是? 每個模板只包含對自己而言 獨一無二 的代碼。 無需多余的部分。 如果想進行站點級的設計修改,僅需修改 base.html ,所有其它模板會立即反映出所作修改。

      以下是其工作方式:

      在加載 current_datetime.html 模板時,模板引擎發(fā)現(xiàn)了 {% extends %} 標簽, 注意到該模板是一個子模板。 模板引擎立即裝載其父模板,即本例中的 base.html 。此時,模板引擎注意到 base.html 中的三個 {% block %} 標簽,并用子模板的內(nèi)容替換這些 block 。因此,引擎將會使用我們在 { block title %} 中定義的標題,對 {% block content %} 也是如此。 所以,網(wǎng)頁標題一塊將由{% block title %}替換,同樣地,網(wǎng)頁的內(nèi)容一塊將由 {% block content %}替換。

     注意由于子模板并沒有定義 footer 塊,模板系統(tǒng)將使用在父模板中定義的值。 父模板 {% block %} 標簽中的內(nèi)容總是被當作一條退路。繼承并不會影響到模板的上下文。 換句話說,任何處在繼承樹上的模板都可以訪問到你傳到模板中的每一個模板變量。你可以根據(jù)需要使用任意多的繼承次數(shù)。 使用繼承的一種常見方式是下面的三層法:

   <1> 創(chuàng)建 base.html 模板,在其中定義站點的主要外觀感受。 這些都是不常修改甚至從不修改的部分。
   <2> 為網(wǎng)站的每個區(qū)域創(chuàng)建 base_SECTION.html 模板(例如, base_photos.html 和 base_forum.html )。這些模板對base.html 進行拓展,
并包含區(qū)域特定的風格與設計。 <3> 為每種類型的頁面創(chuàng)建獨立的模板,例如論壇頁面或者圖片庫。 這些模板拓展相應的區(qū)域模板。

      這個方法可最大限度地重用代碼,并使得向公共區(qū)域(如區(qū)域級的導航)添加內(nèi)容成為一件輕松的工作。

以下是使用模板繼承的一些訣竅:

View Code

八 Models

數(shù)據(jù)庫的配置

1    django默認支持sqlite,mysql, oracle,postgresql數(shù)據(jù)庫。

     <1> sqlite

            django默認使用sqlite的數(shù)據(jù)庫,默認自帶sqlite的數(shù)據(jù)庫驅(qū)動 , 引擎名稱:django.db.backends.sqlite3

     <2> mysql

            引擎名稱:django.db.backends.mysql

2    mysql驅(qū)動程序

  •    MySQLdb(mysql python)
  •    mysqlclient
  •    MySQL
  •    PyMySQL(純python的mysql驅(qū)動程序)

3     在django的項目中會默認使用sqlite數(shù)據(jù)庫,在settings里有如下設置:

           

如果我們想要更改數(shù)據(jù)庫,需要修改如下:

           

View Code

注意:

View Code

ORM(對象關(guān)系映射)

用于實現(xiàn)面向?qū)ο缶幊陶Z言里不同類型系統(tǒng)的數(shù)據(jù)之間的轉(zhuǎn)換,換言之,就是用面向?qū)ο蟮姆绞饺ゲ僮鲾?shù)據(jù)庫的創(chuàng)建表以及增刪改查等操作。

優(yōu)點: 1 ORM使得我們的通用數(shù)據(jù)庫交互變得簡單易行,而且完全不用考慮該死的SQL語句。快速開發(fā),由此而來。

          2 可以避免一些新手程序猿寫sql語句帶來的性能問題。

            比如 我們查詢User表中的所有字段:

            

            新手可能會用select * from  auth_user,這樣會因為多了一個匹配動作而影響效率的。

 缺點:1  性能有所犧牲,不過現(xiàn)在的各種ORM框架都在嘗試各種方法,比如緩存,延遲加載登來減輕這個問題。效果很顯著。

          2  對于個別復雜查詢,ORM仍然力不從心,為了解決這個問題,ORM一般也支持寫raw sql。

          3  通過QuerySet的query屬性查詢對應操作的sql語句

1
2
author_obj=models.Author.objects.filter(id=2)
print(author_obj.query)

     下面要開始學習Django ORM語法了,為了更好的理解,我們來做一個基本的 書籍/作者/出版商 數(shù)據(jù)庫結(jié)構(gòu)。 我們這樣做是因為 這是一個眾所周知的例子,很多SQL有關(guān)的書籍也常用這個舉例。

表(模型)的創(chuàng)建:

實例:我們來假定下面這些概念,字段和關(guān)系

作者模型:一個作者有姓名。

作者詳細模型:把作者的詳情放到詳情表,包含性別,email地址和出生日期,作者詳情模型和作者模型之間是一對一的關(guān)系(one-to-one)(類似于每個人和他的身份證之間的關(guān)系),在大多數(shù)情況下我們沒有必要將他們拆分成兩張表,這里只是引出一對一的概念。

出版商模型:出版商有名稱,地址,所在城市,省,國家和網(wǎng)站。

書籍模型:書籍有書名和出版日期,一本書可能會有多個作者,一個作者也可以寫多本書,所以作者和書籍的關(guān)系就是多對多的關(guān)聯(lián)關(guān)系(many-to-many),一本書只應該由一個出版商出版,所以出版商和書籍是一對多關(guān)聯(lián)關(guān)系(one-to-many),也被稱作外鍵。

View Code

注意1:記得在settings里的INSTALLED_APPS中加入'app01',然后再同步數(shù)據(jù)庫。

注意2: models.ForeignKey("Publish") & models.ForeignKey(Publish)

分析代碼:

       <1>  每個數(shù)據(jù)模型都是django.db.models.Model的子類,它的父類Model包含了所有必要的和數(shù)據(jù)庫交互的方法。并提供了一個簡介漂亮的定義數(shù)據(jù)庫字段的語法。

       <2>  每個模型相當于單個數(shù)據(jù)庫表(多對多關(guān)系例外,會多生成一張關(guān)系表),每個屬性也是這個表中的字段。屬性名就是字段名,它的類型(例如CharField)相當于數(shù)據(jù)庫的字段類型(例如varchar)。大家可以留意下其它的類型都和數(shù)據(jù)庫里的什么字段對應。

       <3>  模型之間的三種關(guān)系:一對一,一對多,多對多。

             一對一:實質(zhì)就是在主外鍵(author_id就是foreign key)的關(guān)系基礎上,給外鍵加了一個UNIQUE=True的屬性;

             一對多:就是主外鍵關(guān)系;(foreign key)

             多對多:(ManyToManyField) 自動創(chuàng)建第三張表(當然我們也可以自己創(chuàng)建第三張表:兩個foreign key)

       <4>  模型常用的字段類型參數(shù)

View Code

       <5>  Field重要參數(shù)

View Code

表的操作(增刪改查):

-------------------------------------增(create  ,  save) -------------------------------

復制代碼
from app01.models import *

    #create方式一:   Author.objects.create(name='Alvin')

    #create方式二:   Author.objects.create(**{"name":"alex"})

    #save方式一:     author=Author(name="alvin")
                    author.save()

    #save方式二:     author=Author()
                    author.name="alvin"
                    author.save()
復制代碼

重點來了------->那么如何創(chuàng)建存在一對多或多對多關(guān)系的一本書的信息呢?(如何處理外鍵關(guān)系的字段如一對多的publisher和多對多的authors)

View Code

-----------------------------------------刪(delete) ---------------------------------------------

>>> Book.objects.filter(id=1).delete()
(3, {'app01.Book_authors': 2, 'app01.Book': 1})

我們表面上刪除了一條信息,實際卻刪除了三條,因為我們刪除的這本書在Book_authors表中有兩條相關(guān)信息,這種刪除方式就是django默認的級聯(lián)刪除。

如果是多對多的關(guān)系: remove()和clear()方法: 

復制代碼
#正向
book = models.Book.objects.filter(id=1)

#刪除第三張表中和女孩1關(guān)聯(lián)的所有關(guān)聯(lián)信息
book.author.clear()        #清空與book中id=1 關(guān)聯(lián)的所有數(shù)據(jù)
book.author.remove(2)  #可以為id
book.author.remove(*[1,2,3,4])     #可以為列表,前面加*

#反向
author = models.Author.objects.filter(id=1)
author.book_set.clear() #清空與boy中id=1 關(guān)聯(lián)的所有數(shù)據(jù)
復制代碼

-----------------------------------------改(update和save) ----------------------------------------

實例:

    

注意:

<1> 第二種方式修改不能用get的原因是:update是QuerySet對象的方法,get返回的是一個model對象,它沒有update方法,而filter返回的是一個QuerySet對象(filter里面的條件可能有多個條件符合,比如name='alvin',可能有兩個name='alvin'的行數(shù)據(jù))。

<2>在“插入和更新數(shù)據(jù)”小節(jié)中,我們有提到模型的save()方法,這個方法會更新一行里的所有列。 而某些情況下,我們只需要更新行里的某幾列。

View Code

      在這個例子里我們可以看到Django的save()方法更新了不僅僅是title列的值,還有更新了所有的列。 若title以外的列有可能會被其他的進程所改動的情況下,只更改title列顯然是更加明智的。更改某一指定的列,我們可以調(diào)用結(jié)果集(QuerySet)對象的update()方法,與之等同的SQL語句變得更高效,并且不會引起競態(tài)條件。

此外,update()方法對于任何結(jié)果集(QuerySet)均有效,這意味著你可以同時更新多條記錄update()方法會返回一個整型數(shù)值,表示受影響的記錄條數(shù)。

注意,這里因為update返回的是一個整形,所以沒法用query屬性;對于每次創(chuàng)建一個對象,想顯示對應的raw sql,需要在settings加上日志記錄部分:

LOGGING

注意:如果是多對多的改:

 

    obj=Book.objects.filter(id=1)[0]
    author=Author.objects.filter(id__gt=2)

    obj.author.clear()
    obj.author.add(*author)

 

 

---------------------------------------查(filter,value等) -------------------------------------

---------->查詢API:

View Code

補充:

extra

---------->惰性機制:

所謂惰性機制:Publisher.objects.all()或者.filter()等都只是返回了一個QuerySet(查詢結(jié)果集對象),它并不會馬上執(zhí)行sql,而是當調(diào)用QuerySet的時候才執(zhí)行。

QuerySet特點:

       <1>  可迭代的

       <2>  可切片

View Code

QuerySet的高效使用:

View Code

---------->對象查詢,單表條件查詢,多表條件關(guān)聯(lián)查詢

View Code

注意:條件查詢即與對象查詢對應,是指在filter,values等方法中的通過__來明確查詢條件。

---------->聚合查詢和分組查詢

<1> aggregate(*args,**kwargs):

   通過對QuerySet進行計算,返回一個聚合值的字典。aggregate()中每一個參數(shù)都指定一個包含在字典中的返回值。即在查詢集上生成聚合。

View Code

<2> annotate(*args,**kwargs):

   可以通過計算查詢結(jié)果中每一個對象所關(guān)聯(lián)的對象集合,從而得出總計值(也可以是平均值或總和),即為查詢集的每一項生成聚合。

       查詢alex出的書總價格                   

       

        查詢各個作者出的書的總價格,這里就涉及到分組了,分組條件是authors__name

           

         查詢各個出版社最便宜的書價是多少

       

---------->F查詢和Q查詢

僅僅靠單一的關(guān)鍵字參數(shù)查詢已經(jīng)很難滿足查詢要求。此時Django為我們提供了F和Q查詢:

View Code

raw sql

django中models的操作,也是調(diào)用了ORM框架來實現(xiàn)的,pymysql 或者mysqldb,所以我們也可以使用原生的SQL語句來操作數(shù)據(jù)庫!

九 admin的配置

admin是django強大功能之一,它能共從數(shù)據(jù)庫中讀取數(shù)據(jù),呈現(xiàn)在頁面中,進行管理。默認情況下,它的功能已經(jīng)非常強大,如果你不需要復雜的功能,它已經(jīng)夠用,但是有時候,一些特殊的功能還需要定制,比如搜索功能,下面這一系列文章就逐步深入介紹如何定制適合自己的admin應用。

如果你覺得英文界面不好用,可以在setting.py 文件中修改以下選項

1
LANGUAGE_CODE = 'en-us'  #LANGUAGE_CODE = 'zh-hans'

一  認識ModelAdmin

   管理界面的定制類,如需擴展特定的model界面需從該類繼承。

二 注冊medel類到admin的兩種方式:

     <1>   使用register的方法

1
admin.site.register(Book,MyAdmin)

     <2>   使用register的裝飾器

1
@admin.register(Book)

三 掌握一些常用的設置技巧

  •     list_display:     指定要顯示的字段
  •     search_fields:  指定搜索的字段
  •     list_filter:        指定列表過濾器
  •     ordering:       指定排序字段
復制代碼
from django.contrib import admin
from app01.models import *
# Register your models here.

# @admin.register(Book)#----->單給某個表加一個定制
class MyAdmin(admin.ModelAdmin):
    list_display = ("title","price","publisher")
    search_fields = ("title","publisher")
    list_filter = ("publisher",)
    ordering = ("price",)
    fieldsets =[
        (None,               {'fields': ['title']}),
        ('price information', {'fields': ['price',"publisher"], 'classes': ['collapse']}),
    ]

admin.site.register(Book,MyAdmin)
admin.site.register(Publish)
admin.site.register(Author)
復制代碼

 

參考文獻:http://www./document/2220.html

 

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    免费在线播放一区二区| 日韩成人高清免费在线| 久久大香蕉精品在线观看 | 色综合久久中文综合网| 欧美午夜色视频国产精品| 97人摸人人澡人人人超碰| 懂色一区二区三区四区| 欧美成人欧美一级乱黄| 一区二区三区免费公开| 亚洲欧美日韩综合在线成成| 99亚洲综合精品成人网色播| 搡老妇女老熟女一区二区| 精品综合欧美一区二区三区| 粉嫩内射av一区二区| 夜夜躁狠狠躁日日躁视频黑人| 美女激情免费在线观看| 亚洲中文字幕人妻系列| 噜噜中文字幕一区二区| 亚洲欧美一二区日韩高清在线 | 亚洲另类欧美综合日韩精品| 视频在线播放你懂的一区| 亚洲国产成人爱av在线播放下载| 爽到高潮嗷嗷叫之在现观看| 九九热在线视频精品免费| 国产又粗又深又猛又爽又黄| 亚洲最新一区二区三区| 亚洲国产一级片在线观看| 国产精品一区二区成人在线| 亚洲一区二区三区三州| 国产欧美一区二区另类精品| 国产欧美亚洲精品自拍| 国产精品一区二区有码| 亚洲国产av在线视频| 国产内射一级二级三级| 99久久成人精品国产免费| 激情中文字幕在线观看| 97人妻精品一区二区三区免| 国产丝袜美女诱惑一区二区| 久久大香蕉一区二区三区| 高清免费在线不卡视频| 欧美日韩无卡一区二区|