Python自動化開發課堂筆記【Day15】- Django基礎

WEB框架html

框架,即framework,特指爲解決一個開放性問題而設計的具備必定約束性的支撐結構,使用框架能夠幫你快速開發特定的系統,簡單地說,就是你用別人搭建好的舞臺來作表演。前端

對於全部的Web應用,本質上其實就是一個socket服務端,用戶的瀏覽器其實就是一個socket客戶端。python

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

若是要動態生成HTML,就須要把上述步驟本身來實現。不過,接受HTTP請求、解析HTTP請求、發送HTTP響應都是苦力活,若是咱們本身來寫這些底層代碼,還沒開始寫動態HTML呢,就得花個把月去讀HTTP規範。jquery

正確的作法是底層代碼由專門的服務器軟件實現,咱們用Python專一於生成HTML文檔。由於咱們不但願接觸到TCP鏈接、HTTP原始請求和響應格式,因此,須要一個統一的接口,讓咱們專心用Python編寫Web業務。git

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

MTV模式web

  Django的MTV模式本質是各組件之間爲了保持鬆耦合關係,Django的MTV分別表明:正則表達式

       Model(模型):負責業務對象與數據庫的對象(ORM)sql

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

       View(視圖):負責業務邏輯,並在適當的時候調用Model和Template

       此外,Django還有一個url分發器,它的做用是將一個個URL的頁面請求分發給不一樣的view處理,view再調用相應的Model和Template

Django基本命令

1. 建立一個django project

django-admin.py startproject mysite

當前目錄下會生成mysite的工程,目錄結構以下:

manage.py ----- Django項目裏面的工具,經過它能夠調用django shell和數據庫等。
settings.py ---- 包含了項目的默認設置,包括數據庫信息,調試標誌以及其餘一些工做的變量。
urls.py ----- 負責把URL模式映射到應用程序。

2. 在mysite目錄下建立應用

python manage.py startapp Myproject

3. 啓動django項目

python manage.py runserver 8080

4. 同步更改數據庫表或字段

python manage.py syncdb
     
注意:Django 1.7.1 及以上的版本須要用如下命令
python manage.py makemigrations
python manage.py migrate

這種方法能夠建立表,當你在models.py中新增了類時,運行它就能夠自動在數據庫中建立表了,不用手動建立。

5. 清空數據庫

python manage.py flush

此命令會詢問是 yes 仍是 no, 選擇 yes 會把數據所有清空掉,只留下空表。

6. 建立超級管理員

python manage.py createsuperuser
     
# 按照提示輸入用戶名和對應的密碼就行了郵箱能夠留空,用戶名和密碼必填
     
# 修改 用戶密碼能夠用:

python manage.py changepassword username

7. Django 項目環境終端

python manage.py shell

這個命令和 直接運行 python 進入 shell 的區別是:你能夠在這個 shell 裏面調用當前項目的 models.py 中的 API,對於操做數據的測試很是方便。

8. Django 項目環境終端

python manage.py dbshell

Django 會自動進入在settings.py中設置的數據庫,若是是 MySQL 或 postgreSQL,會要求輸入數據庫用戶密碼。

在這個終端能夠執行數據庫的SQL語句。若是您對SQL比較熟悉,可能喜歡這種方式。

9. 更多命令

python manage.py

查看全部的命令,忘記子名稱的時候特別有用。

10. static配置

STATIC文件還能夠配置STATICFILES_DIRS,指定額外的靜態文件存儲位置。
    #  STATIC_URL的含義與MEDIA_URL相似。

    # ----------------------------------------------------------------------------
    #注意1:
        #爲了後端的更改不會影響前端的引入,避免形成前端大量修改

        STATIC_URL = '/static/'               #引用名
        STATICFILES_DIRS = (
            os.path.join(BASE_DIR,"statics")  #實際名 ,即實際文件夾的名字
        )

        #django對引用名和實際名進行映射,引用時,只能按照引用名來,不能按實際名去找
        #<script src="/statics/jquery-3.1.1.js"></script>
        #------error-----不能直接用,必須用STATIC_URL = '/static/':
        #<script src="/static/jquery-3.1.1.js"></script>

    #注意2(statics文件夾寫在不一樣的app下,靜態文件的調用):

        STATIC_URL = '/static/'

        STATICFILES_DIRS=(
            ('hello',os.path.join(BASE_DIR,"app01","statics")) ,
        )

        #<script src="/static/hello/jquery-1.8.2.min.js"></script>

    #注意3:
        STATIC_URL = '/static/'
        {% load staticfiles %}
       # <script src={% static "jquery-1.8.2.min.js" %}></script>

路由配置系統(URLconf)

URL配置(URLconf)就像Django 所支撐網站的目錄。它的本質是URL與要爲該URL調用的視圖函數之間的映射表;你就是以這種方式告訴Django,對於這個URL調用這段代碼,對於那個URL調用那段代碼。

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


參數說明:

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

1. URLconf的正則字符串參數

  a. 簡單配置

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

NOTE:
    1 一旦匹配成功則再也不繼續
    2 若要從URL 中捕獲一個值,只須要在它周圍放置一對圓括號。
    3 不須要添加一個前導的反斜槓,由於每一個URL 都有。例如,應該是^articles 而不是 ^/articles。
    4 每一個正則表達式前面的'r' 是可選的可是建議加上。

一些請求的例子:

    /articles/2005/3/ 不匹配任何URL 模式,由於列表中的第三個模式要求月份應該是兩個數字。
    /articles/2003/ 將匹配列表中的第一個模式不是第二個,由於模式按順序匹配,第一個會首先測試是否匹配。
    /articles/2005/03/ 請求將匹配列表中的第三個模式。Django 將調用函數
                       views.month_archive(request, '2005', '03')。

#設置項是否開啓URL訪問地址後面不爲/跳轉至帶有/的路徑
APPEND_SLASH=True

b. 有名分組(named group)

上面的示例使用簡單的、沒有命名的正則表達式組(經過圓括號)來捕獲URL 中的值並以位置 參數傳遞給視圖。在更高級的用法中,可使用命名的正則表達式組來捕獲URL 中的值並以關鍵字 參數傳遞給視圖。

在Python 正則表達式中,命名正則表達式組的語法是(?P<name>pattern),其中name 是組的名稱,pattern 是要匹配的模式。

下面是以上URLconf 使用命名組的重寫:

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

這個實現與前面的示例徹底相同,只有一個細微的差異:捕獲的值做爲關鍵字參數而不是位置參數傳遞給視圖函數。例如:

/articles/2005/03/    
請求將調用views.month_archive(request, year='2005', month='03')函數
/articles/2003/03/03/ 
請求將調用函數views.article_detail(request, year='2003', month='03', day='03')。

在實際應用中,這意味你的URLconf 會更加明晰且不容易產生參數順序問題的錯誤 —— 你能夠在你的視圖函數定義中從新安排參數的順序。固然,這些好處是以簡潔爲代價;有些開發人員認爲命名組語法醜陋而繁瑣。

    c. URLconf 在什麼上查找

URLconf 在請求的URL 上查找,將它當作一個普通的Python 字符串。不包括GET和POST參數以及域名。

例如,http://www.example.com/myapp/ 請求中,URLconf 將查找myapp/

在http://www.example.com/myapp/?page=3 請求中,URLconf 仍將查找myapp/

URLconf 不檢查請求的方法。換句話講,全部的請求方法 —— 同一個URL的POSTGETHEAD等等 —— 都將路由到相同的函數。

d. 捕獲的參數永遠是字符串

每一個捕獲的參數都做爲一個普通的Python 字符串傳遞給視圖,不管正則表達式使用的是什麼匹配方式。例如,下面這行URLconf 中:

url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

views.year_archive() 的year 參數將是一個字符串

    e. 指定視圖參數的默認值

      有一個方便的小技巧是指定視圖參數的默認值。 下面是一個URLconf 和視圖的示例:

# URLconf
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]

# View (in blog/views.py)
def page(request, num="1"):

在上面的例子中,兩個URL模式指向同一個視圖views.page —— 可是第一個模式不會從URL 中捕獲任何值。若是第一個模式匹配,page() 函數將使用num參數的默認值"1"。若是第二個模式匹配,page() 將使用正則表達式捕獲的num 值。

f. Including other URLconfs

from django.conf.urls import include, url

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

編寫視圖

一個視圖函數,或者簡短來講叫作視圖,是一個簡單的Python函數,它接受web請求,而且返回web響應。響應能夠是一張網頁的HTML內容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片. . . 是任何東西均可以。不管視圖自己包含什麼邏輯,都要返回響應。代碼寫在哪裏也無所謂,只要它在你的Python目錄下面。除此以外沒有更多的要求了——能夠說「沒有什麼神奇的地方」。爲了可以把代碼放在某個地方,慣例是把視圖放在叫作views.py的文件中,而後把它放到你的項目或者應用目錄裏。

1. 一個簡單的視圖

下面是一個返回當前日期和時間做爲HTML文檔的視圖:

from django.http import HttpResponse
import datetime

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

讓咱們逐行閱讀上面的代碼:

    • 首先,咱們從 django.http模塊導入了HttpResponse類,以及Python的datetime庫。
    • 接着,咱們定義了current_datetime函數。它是一個視圖函數。每一個視圖函數都應接收HttpRequest對象做爲第一個參數,通常叫作request。
    • 注意視圖函數的名稱並不重要;不須要用一個統一的命名方式來命名,以便讓Django識別它。咱們將其命名爲current_datetime,是由於這個名稱可以精確地反映出它的功能。
    • 這個視圖會返回一個HttpResponse對象,其中包含生成的響應。每一個視圖函數都要返回HttpResponse對象

  2. 快捷函數

    a. render函數

---------------render(request, template_name[, context])

結合一個給定的模板和一個給定的上下文字典,並返回一個渲染後的 HttpResponse 對象。

參數:
     request: 用於生成響應的請求對象。

     template_name:要使用的模板的完整名稱,可選的參數

     context:添加到模板上下文的一個字典。默認是一個空字典。若是字典中的某個值是可調用的,視圖將在渲染模板以前調用它。

     content_type:生成的文檔要使用的MIME類型。默認爲DEFAULT_CONTENT_TYPE 設置的值。

     status:響應的狀態碼。默認爲200。

    b. redirect函數

-----------------------------------url.py

 url(r"login",   views.login),
 url(r"yuan_back",   views.yuan_back),

-----------------------------------views.py
def login(req):
    if req.method=="POST":
        if 1:
            # return redirect("/yuan_back/")
            name="yuanhao"

            return render(req,"my backend.html",locals())

    return render(req,"login.html",locals())


def yuan_back(req):

    name="苑昊"

    return render(req,"my backend.html",locals())

-----------------------------------login.html

<form action="/login/" method="post">
    <p>姓名<input type="text" name="username"></p>
    <p>性別<input type="text" name="sex"></p>
    <p>郵箱<input type="text" name="email"></p>
    <p><input type="submit" value="submit"></p>
</form>
-----------------------------------my backend.html
<h1>用戶{{ name }}你好</h1>

#總結: render和redirect的區別:
#   1 if render的頁面須要模板語言渲染,須要的將數據庫的數據加載到html,那麼全部的這一部分
#     除了寫在yuan_back的視圖函數中,必須還要寫在login中,代碼重複,沒有解耦.

#   2 the most important: url沒有跳轉到/yuan_back/,而是還在/login/,因此當刷新後
#     又得從新登陸.

Template

1. 模板系統的介紹

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

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

儘管這種技術便於解釋視圖是如何工做的,但直接將HTML硬編碼到你的視圖裏卻並非一個好主意。 讓咱們來看一下爲何:

    • 對頁面設計進行的任何改變都必須對 Python 代碼進行相應的修改。 站點設計的修改每每比底層 Python 代碼的修改要頻繁得多,所以若是能夠在不進行 Python 代碼修改的狀況下變動設計,那將會方便得多。

    • Python 代碼編寫和 HTML 設計是兩項不一樣的工做,大多數專業的網站開發環境都將他們分配給不一樣的人員(甚至不一樣部門)來完成。 設計者和HTML/CSS的編碼人員不該該被要求去編輯Python的代碼來完成他們的工做。

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

基於這些緣由,將頁面的設計和Python的代碼分離開會更乾淨簡潔更容易維護。 咱們可使用 Django的 模板系統 (Template System)來實現這種模式,這就是本章要具體討論的問題。

python的模板:HTML代碼+邏輯控制代碼

  2. 模板支持的語法

    a. 變量(使用雙大括號來引用變量)

語法格式:       {{var_name}}

----------------------------------Template和Context對象 
>>> python manange.py shell  (進入該django項目的環境)
>>> from django.template import Context, Template
>>> t = Template('My name is {{ name }}.')
>>> c = Context({'name': 'Stephane'})
>>> t.render(c)
'My name is Stephane.'


# 同一模板,多個上下文,一旦有了模板對象,你就能夠經過它渲染多個context,不管什麼時候咱們均可以
# 像這樣使用同一模板源渲染多個context,只進行 一次模板建立而後屢次調用render()方法渲染會
# 更爲高效:
# Low
for name in ('John', 'Julie', 'Pat'):
    t = Template('Hello, {{ name }}')
    print t.render(Context({'name': name}))

# Good
t = Template('Hello, {{ name }}')
for name in ('John', 'Julie', 'Pat'):
    print t.render(Context({'name': name}))

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

#最好是用幾個例子來講明一下。
# 首先,句點可用於訪問列表索引,例如:

>>> from django.template import Template, Context
>>> t = Template('Item 2 is {{ items.2 }}.')
>>> c = Context({'items': ['apples', 'bananas', 'carrots']})
>>> t.render(c)
'Item 2 is carrots.'

#假設你要向模板傳遞一個 Python 字典。 要經過字典鍵訪問該字典的值,可以使用一個句點:
>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name }} is {{ person.age }} years old.')
>>> c = Context({'person': person})
>>> t.render(c)
'Sally is 43 years old.'

#一樣,也能夠經過句點來訪問對象的屬性。 比方說, Python 的 datetime.date 對象有
#year 、 month 和 day 幾個屬性,你一樣能夠在模板中使用句點來訪問這些屬性:

>>> from django.template import Template, Context
>>> import datetime
>>> d = datetime.date(1993, 5, 2)
>>> d.year
1993
>>> d.month
5
>>> d.day
2
>>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.')
>>> c = Context({'date': d})
>>> t.render(c)
'The month is 5 and the year is 1993.'

# 這個例子使用了一個自定義的類,演示了經過實例變量加一點(dots)來訪問它的屬性,這個方法適
# 用於任意的對象。
>>> from django.template import Template, Context
>>> class Person(object):
...     def __init__(self, first_name, last_name):
...         self.first_name, self.last_name = first_name, last_name
>>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
>>> c = Context({'person': Person('John', 'Smith')})
>>> t.render(c)
'Hello, John Smith.'

# 點語法也能夠用來引用對象的方法。 例如,每一個 Python 字符串都有 upper() 和 isdigit()
# 方法,你在模板中可使用一樣的句點語法來調用它們:
>>> from django.template import Template, Context
>>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
>>> t.render(Context({'var': 'hello'}))
'hello -- HELLO -- False'
>>> t.render(Context({'var': '123'}))
'123 -- 123 -- True'

# 注意這裏調用方法時並* 沒有* 使用圓括號 並且也沒法給該方法傳遞參數;你只能調用不需參數的
# 方法。

    c. 標籤(tag)的使用(使用大括號和百分比的組合來表示使用tag)

語法格式:    {% tags %}

{% if %} 的使用 

{% if %}標籤計算一個變量值,若是是「true」,即它存在、不爲空而且不是false的boolean值,系統則會顯示{% if %}和{% endif %}間的全部內容

{% if num >= 100 and 8 %}

    {% if num > 200 %}
        <p>num大於200</p>
    {% else %}
        <p>num大於100小於200</p>
    {% endif %}

{% elif num < 100%}
    <p>num小於100</p>

{% else %}
    <p>num等於100</p>

{% endif %}



{% if %} 標籤接受and,or或者not來測試多個變量值或者否認一個給定的變量
{% if %} 標籤不容許同一標籤裏同時出現and和or,不然邏輯容易產生歧義,例以下面的標籤是不合法的:

{% if obj1 and obj2 or obj3 %} 



{% for %}的使用

{% for %}標籤容許你按順序遍歷一個序列中的各個元素,每次循環模板系統都會渲染{% for %}和{% endfor %}之間的全部內容

<ul>
{% for obj in list %}
    <li>{{ obj.name }}</li>
{% endfor %}
</ul>


#在標籤裏添加reversed來反序循環列表:

    {% for obj in list reversed %}
    ...
    {% endfor %}

#{% for %}標籤能夠嵌套:

    {% for country in countries %}
        <h1>{{ country.name }}</h1>
        <ul>
         {% for city in country.city_list %}
            <li>{{ city }}</li>
         {% endfor %}
        </ul>
    {% endfor %}


#系統不支持中斷循環,系統也不支持continue語句,{% for %}標籤內置了一個forloop模板變量,
#這個變量含有一些屬性能夠提供給你一些關於循環的信息

1,forloop.counter表示循環的次數,它從1開始計數,第一次循環設爲1:

    {% for item in todo_list %}
        <p>{{ forloop.counter }}: {{ item }}</p>
    {% endfor %}
2,forloop.counter0 相似於forloop.counter,但它是從0開始計數,第一次循環設爲0
3,forloop.revcounter
4,forloop.revcounter0
5,forloop.first當第一次循環時值爲True,在特別狀況下頗有用:

    
    {% for object in objects %}   
         {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}   
         {{ object }}   
        </li>  
    {% endfor %}  
    
# 富有魔力的forloop變量只能在循環中獲得,當模板解析器到達{% endfor %}時forloop就消失了
# 若是你的模板context已經包含一個叫forloop的變量,Django會用{% for %}標籤替代它
# Django會在for標籤的塊中覆蓋你定義的forloop變量的值
# 在其餘非循環的地方,你的forloop變量仍然可用


#{% empty %}

{{li }}
      {%  for i in li %}
          <li>{{ forloop.counter0 }}----{{ i }}</li>
      {% empty %}
          <li>this is empty!</li>
      {% endfor %}

#         [11, 22, 33, 44, 55]
#            0----11
#            1----22
#            2----33
#            3----44
#            4----55
csrf_token標籤

用於生成csrf_token的標籤,用於防治跨站攻擊驗證。 其實,這裏是會生成一個input標籤,和其餘表單標籤一塊兒提交給後臺的。

{% url %}

引用路由配置的地址

<form action="{% url "bieming"%}" >
          <input type="text">
          <input type="submit"value="提交">
          {%csrf_token%}
</form>
{% with %}

用更簡單的變量名替代複雜的變量名

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

禁止render

{% verbatim %}
         {{ hello }}
{% endverbatim %}
{% load %}加載標籤庫:自定義filter和simple_tag

a、在app中建立templatetags模塊(必須的)

b、建立任意 .py 文件,如:my_tags.py

c、在使用自定義simple_tag和filter的html文件中導入以前建立的 my_tags.py :{% load my_tags %}

d、使用simple_tag和filter(如何調用)

e、在settings中的INSTALLED_APPS配置當前app,否則django沒法找到自定義的simple_tag.

注意:

filter能夠用在if等語句後,simple_tag不能夠

{% if num|filter_multi:30 > 100 %}
    {{ num|filter_multi:30 }}
{% endif %}

數據庫與ORM

1. 數據庫配置

1    django默認支持sqlite,mysql, oracle,postgresql數據庫。

     <1> sqlite

            django默認使用sqlite的數據庫,默認自帶sqlite的數據庫驅動 , 引擎名稱:django.db.backends.sqlite3

     <2> mysql

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

2    mysql驅動程序

    •    MySQLdb(mysql python)

    •    mysqlclient

    •    MySQL

    •    PyMySQL(純python的mysql驅動程序)

2. ORM表模型

表(模型)的建立:

實例:咱們來假定下面這些概念,字段和關係

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

做者詳細模型:把做者的詳情放到詳情表,包含性別,email地址和出生日期,做者詳情模型和做者模型之間是一對一的關係(one-to-one)(相似於每一個人和他的身份證之間的關係),在大多數狀況下咱們沒有必要將他們拆分紅兩張表,這裏只是引出一對一的概念。

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

書籍模型:書籍有書名和出版日期,一本書可能會有多個做者,一個做者也能夠寫多本書,因此做者和書籍的關係就是多對多的關聯關係(many-to-many),一本書只應該由一個出版商出版,因此出版商和書籍是一對多關聯關係(one-to-many),也被稱做外鍵。

from django.db import models<br>
class Publisher(models.Model):
    name = models.CharField(max_length=30, verbose_name="名稱")
    address = models.CharField("地址", max_length=50)
    city = models.CharField('城市',max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()
 
    class Meta:
        verbose_name = '出版商'
        verbose_name_plural = verbose_name
 
    def __str__(self):
        return self.name
 
class Author(models.Model):
    name = models.CharField(max_length=30)
    def __str__(self):
        return self.name
 
class AuthorDetail(models.Model):
    sex = models.BooleanField(max_length=1, choices=((0, ''),(1, ''),))
    email = models.EmailField()
    address = models.CharField(max_length=50)
    birthday = models.DateField()
    author = models.OneToOneField(Author)
 
class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=2,default=10)
    def __str__(self):
        return self.title

3. ORM之增(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()

4. ORM之刪(delete)

>>> Book.objects.filter(id=1).delete()
(3, {'app01.Book_authors': 2, 'app01.Book': 1})
咱們表面上刪除了一條信息,實際卻刪除了三條,由於咱們刪除的這本書在Book_authors表中有兩條相關信息,這種刪除方式就是django默認的級聯刪除。

5. ORM之改(update和save)

#---------------- update方法直接設定對應屬性----------------
    models.Book.objects.filter(id=3).update(title="PHP")
    ##sql:
    ##UPDATE "app01_book" SET "title" = 'PHP' WHERE "app01_book"."id" = 3; args=('PHP', 3)


#--------------- save方法會將全部屬性從新設定一遍,效率低-----------
    obj=models.Book.objects.filter(id=3)[0]
    obj.title="Python"
    obj.save()
# SELECT "app01_book"."id", "app01_book"."title", "app01_book"."price", 
# "app01_book"."color", "app01_book"."page_num", 
# "app01_book"."publisher_id" FROM "app01_book" WHERE "app01_book"."id" = 3 LIMIT 1; 
# 
# UPDATE "app01_book" SET "title" = 'Python', "price" = 3333, "color" = 'red', "page_num" = 556,
# "publisher_id" = 1 WHERE "app01_book"."id" = 3; 

6. ORM之查(filter,value) 

  a. 查詢API

  b. QuerySet與惰性機制

  c. 對象查詢,單表條件查詢,多表條件關聯查詢

  d. 聚合查詢和分組查詢

  e. F查詢和Q查詢

相關文章
相關標籤/搜索