Python Django 基礎

一 什麼是web框架?

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

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

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用文件保存好,用一個現成的HTTP服務器軟件,接收用戶請求,從文件中讀取HTML,返回。前端

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

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

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

 -----------------------------模擬框架實現功能---------------------------git

所需的HTML代碼自行添加

from wsgiref.simple_server import make_server
import time

def yhr(req):
    f = open("index2.html","rb")
    data = f.read()
    return data

def login(req):
    print(req["QUERY_STRING"])
    return b"welcome !"
def singup(req):
    pass

def show_time(req):
    times =time.ctime()
    # return ("<h1>time:%s</h1>"%str(times)).encode("utf8")
    f = open("show_time.html","rb")
    data = f.read()
    data = data.decode("utf8")
    data = data.replace("{{time}}",str(times))

    return data.encode("utf8")
def router():
    url_patterns = [
        ("/login",login),
        ("/singup",singup),
        ("/yhr",yhr),
        ("/show_time",show_time)
    ]
    return url_patterns


def application(environ, start_response):
    print("path",environ["PATH_INFO"])
    path = environ["PATH_INFO"] # 取數據
    start_response('200 OK', [('Content-Type', 'text/html')])
    url_patterns = router()

    func = None
    for item in url_patterns:
        if item[0] == path:
            func = item[1]
            break
    if func:
        return [func(environ)]
    else:
        return [b"404"]

httpd = make_server('', 8000, application)

print('Serving HTTP on port 8000...')
# 開始監聽HTTP請求:
httpd.serve_forever()  

二 MVC和MTV模式

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

模型負責業務對象與數據庫的對象(ORM),視圖負責與用戶的交互(頁面),控制器(C)接受用戶的輸入調用模型和視圖完成用戶的請求。正則表達式

 

Django的MTV模式本質上與MVC模式沒有什麼差異,也是各組件之間爲了保持鬆耦合關係,只是定義上有些許不一樣,Django的MTV分別表明:sql

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

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

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

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

 

 三 django的流程和命令行工具

django實現流程

django
    #安裝: pip3 install django

          添加環境變量 :在安裝Python3的lib---》site.packages---》django---》bin

    #1  建立project
       django-admin startproject mysite

       ---mysite

          ---settings.py
          ---url.py
          ---wsgi.py

       ---- manage.py(啓動文件)  

    #2  建立APP       
       python mannage.py startapp  app01

    #3  settings配置
    
       TEMPLATES

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

       STATIC_URL = '/static/' 
       #  咱們只能用 STATIC_URL,但STATIC_URL會按着你的STATICFILES_DIRS去找#4  根據需求設計代碼
           url.py
           view.py

    #5  使用模版
       render(req,"index.html")   

    #6  啓動項目
       python manage.py runserver  127.0.0.1:8090

    #7  鏈接數據庫,操做數據
       model.py

django的命令行工具

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

<1> 建立一個django工程 : django-admin.py startproject mysite

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

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

<2>在mysite目錄下建立blog應用: python manage.py startapp blog 

 

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

       這樣咱們的django就啓動起來了!當咱們訪問:http://127.0.0.1:8080/時就能夠看到:

 

<4>生成同步數據庫的腳本:python manage.py makemigrations  

                     同步數據庫:  python manage.py migrate   

       注意:在開發過程當中,數據庫同步誤操做以後,不免會遇到後面不能同步成功的狀況,解決這個問題的一個簡單粗暴方法是把migrations目錄下

                的腳本(除__init__.py以外)所有刪掉,再把數據庫刪掉以後建立一個新的數據庫,數據庫同步操做再從新作一遍。            

<5>當咱們訪問http://127.0.0.1:8080/admin/時,會出現:

 因此咱們須要爲進入這個項目的後臺建立超級管理員:python manage.py createsuperuser設置好用戶名和密碼後即可登陸啦!

<6>清空數據庫:python manage.py  flush

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

       admin 是Django 自帶的一個後臺數據庫管理系統。

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

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

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

四 Django的配置文件(settings)

  1 1、概述:
  2 
  3      #靜態文件交由Web服務器處理,Django自己不處理靜態文件。簡單的處理邏輯以下(以nginx爲例):
  4 
  5      #          URI請求-----> 按照Web服務器裏面的配置規則先處理,以nginx爲例,主要求配置在nginx.
  6                              #conf裏的location
  7 
  8                          |---------->若是是靜態文件,則由nginx直接處理
  9 
 10                          |---------->若是不是則交由Django處理,Django根據urls.py裏面的規則進行匹配
 11 
 12     # 以上是部署到Web服務器後的處理方式,爲了便於開發,Django提供了在開發環境的對靜態文件的處理機制,方法是這樣:
 13 
 14     #1、在INSTALLED_APPS裏面加入'django.contrib.staticfiles',
 15 
 16     #2、在urls.py裏面加入
 17        if settings.DEBUG:  
 18            urlpatterns += patterns('', url(r'^media/(?P<path>.*)$', 
 19            'django.views.static.serve', {'document_root': settings.MEDIA_ROOT }),   
 20             url(r'^static/(?P<path>.*)$',
 21           'django.views.static.serve',{'document_root':settings.STATIC_ROOT}), )  
 22 
 23     # 3、這樣就能夠在開發階段直接使用靜態文件了。
 24 
 25 2、MEDIA_ROOT和MEDIA_URL
 26 
 27         #而靜態文件的處理又包括STATIC和MEDIA兩類,這每每容易混淆,在Django裏面是這樣定義的:
 28 
 29         #MEDIA:指用戶上傳的文件,好比在Model裏面的FileFIeld,ImageField上傳的文件。若是你定義
 30 
 31         #MEDIA_ROOT=c:\temp\media,那麼File=models.FileField(upload_to="abc/")#,上傳的文件就會被保存到c:\temp\media\abc  
 32         #eg:
 33             class blog(models.Model):  
 34                    Title=models.charField(max_length=64)  
 35                    Photo=models.ImageField(upload_to="photo") 
 36         #     上傳的圖片就上傳到c:\temp\media\photo,而在模板中要顯示該文件,則在這樣寫
 37         #在settings裏面設置的MEDIA_ROOT必須是本地路徑的絕對路徑,通常是這樣寫:
 38                  BASE_DIR= os.path.abspath(os.path.dirname(__file__))  
 39                  MEDIA_ROOT=os.path.join(BASE_DIR,'media/').replace('\\','/') 
 40 
 41         #MEDIA_URL是指從瀏覽器訪問時的地址前綴,舉個例子:
 42             MEDIA_ROOT=c:\temp\media\photo  
 43             MEDIA_URL="/data/"
 44         #在開發階段,media的處理由django處理:
 45 
 46         #    訪問http://localhost/data/abc/a.png就是訪問c:\temp\media\photo\abc\a.png
 47 
 48         #    在模板裏面這樣寫<img src="{{MEDIA_URL}}abc/a.png">
 49 
 50         #    在部署階段最大的不一樣在於你必須讓web服務器來處理media文件,所以你必須在web服務器中配置,
 51         #  以便能讓web服務器能訪問media文件
 52         #    以nginx爲例,能夠在nginx.conf裏面這樣:
 53 
 54                  location ~/media/{
 55                        root/temp/
 56                        break;
 57                     }
 58 
 59         #    具體能夠參考如何在nginx部署django的資料。
 60 
 61 3、STATIC_ROOT和STATIC_URL、
 62     STATIC主要指的是如css,js,images這樣文件,在settings裏面能夠配置STATIC_ROOT和STATIC_URL,
 63     配置方式與MEDIA_ROOT是同樣的,可是要注意
 64 
 65     #STATIC文件通常保存在如下位置:
 66 
 67     #1、STATIC_ROOT:在settings裏面設置,通常用來放一些公共的js,css,images等。
 68 
 69     #2、app的static文件夾,在每一個app所在文夾都可以創建一個static文件夾,而後當運行collectstatic時,
 70     #    Django會遍歷INSTALL_APPS裏面全部app的static文件夾,將裏面全部的文件複製到STATIC_ROOT。所以,
 71     #   若是你要創建可複用的app,那麼你要將該app所須要的靜態文件放在static文件夾中。
 72 
 73     # 也就是說一個項目引用了不少app,那麼這個項目所須要的css,images等靜態文件是分散在各個app的static文件的,比
 74     #  較典型的是admin應用。當你要發佈時,須要將這些分散的static文件收集到一個地方就是STATIC_ROOT。
 75 
 76     #3、STATIC文件還能夠配置STATICFILES_DIRS,指定額外的靜態文件存儲位置。
 77     #  STATIC_URL的含義與MEDIA_URL相似。
 78 
 79     # ----------------------------------------------------------------------------
 80     #注意1:
 81         #爲了後端的更改不會影響前端的引入,避免形成前端大量修改
 82 
 83         STATIC_URL = '/static/'               #引用名
 84         STATICFILES_DIRS = (
 85             os.path.join(BASE_DIR,"statics")  #實際名 ,即實際文件夾的名字
 86         )
 87 
 88         #django對引用名和實際名進行映射,引用時,只能按照引用名來,不能按實際名去找
 89         #<script src="/statics/jquery-3.1.1.js"></script>
 90         #------error-----不能直接用,必須用STATIC_URL = '/static/':
 91         #<script src="/static/jquery-3.1.1.js"></script>
 92 
 93     #注意2(statics文件夾寫在不一樣的app下,靜態文件的調用):
 94 
 95         STATIC_URL = '/static/'
 96 
 97         STATICFILES_DIRS=(
 98             ('hello',os.path.join(BASE_DIR,"app01","statics")) ,
 99         )
100 
101         #<script src="/static/hello/jquery-1.8.2.min.js"></script>
102 
103     #注意3:
104         STATIC_URL = '/static/'
105         {% load staticfiles %}
106        # <script src={% static "jquery-1.8.2.min.js" %}></script>
View Code

其它重要參數設置:

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

 

五 Django URL (路由系統)

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

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

參數說明:

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

例如:url(r'student', views.student,{"time:t"},name="stu"),

5.1 這是一個示例URLconf 

 1 from django.conf.urls import url
 2 from django.contrib import admin
 3 
 4 from app01 import views
 5 
 6 urlpatterns = [
 7 
 8     url(r'^articles/2003/$', views.special_case_2003),
 9 
10     #url(r'^articles/[0-9]{4}/$', views.year_archive),
11 
12     url(r'^articles/([0-9]{4})/$', views.year_archive),  #no_named group
13 
14     url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
15 
16     url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
17 
18 ]
View Code

上面的例子中使用簡單,non-named正則表達式組(經過括號)捕捉到的URL,將他們做爲一個視圖的位置參數。在更高級的用法,可使用指定的正則表達式組捕獲的URL部分並將它們做爲關鍵字參數傳遞給一個視圖。

在Python中正則表達式,指定的正則表達式的語法組(? P <名稱>模式),在那裏的名字是集團的名稱和模式是模式匹配。

這是上面的例子URLconf,重寫使用命名組:

1 import re
2 
3 ret=re.search('(?P<id>\d{3})/(?P<name>\w{3})','weeew34ttt123/ooo')
4 
5 print(ret.group())
6 print(ret.group('id'))
7 print(ret.group('name'))
View Code
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),
]

這完成了前面的例子同樣,有一個微妙的差別:捕獲的值傳遞給視圖函數做爲關鍵字參數而不是位置參數。

5.3 經過額外的選項來查看功能

URLconfs有鉤,容許您將額外的參數傳遞給視圖功能,做爲一個Python字典。

django.conf.urls.url()函數能夠用一個可選的第三個參數應該字典的額外關鍵字參數傳遞到視圖的功能。

例子:

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

在本例中,請求/博客/ 2005 / Django將調用視圖。year_archive(請求,年= ' 2005 ',foo = '酒吧')。

這種技術用於聚合框架經過元數據和視圖選項。

處理衝突

能夠有一個URL模式捕獲關鍵字參數,並經過參數具備相同名字的字典的額外參數。當這種狀況發生時,在字典裏的參數將用來替代參數捕獲的URL。

5.4 參數名稱

URL
urlpatterns = [
    url(r'^index',views.index,name='bieming'),
    url(r'^admin/', admin.site.urls),
    # 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),

]
###################
views視圖函數
def index(req):
    if req.method=='POST':
        username=req.POST.get('username')
        password=req.POST.get('password')
        if username=='alex' and password=='123':
            return HttpResponse("登錄成功")



    return render(req,'index.html')

#####################
templates裏面的HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#     <form action="/index/" method="post">#}
     <form action="{% url 'bieming' %}" method="post">
         用戶名:<input type="text" name="username">
         密碼:<input type="password" name="password">
         <input type="submit" value="submit">
     </form>
</body>
</html>


#######################

5.5 包括其餘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(視圖函數)

http請求中產生兩個核心對象:

        http請求:HttpRequest對象

        http響應:HttpResponse對象

所在位置:django.http

以前咱們用到的參數request就是HttpRequest    檢測方法:isinstance(request,HttpRequest)

1 HttpRequest對象的屬性和方法:

 

# path:       請求頁面的全路徑,不包括域名
#
# method:     請求中使用的HTTP方法的字符串表示。全大寫表示。例如
#
#                    if  req.method=="GET":
#
#                              do_something()
#
#                    elseif req.method=="POST":
#
#                              do_something_else()
#
# GET:         包含全部HTTP GET參數的類字典對象
#
# POST:       包含全部HTTP POST參數的類字典對象
#
#              服務器收到空的POST請求的狀況也是可能發生的,也就是說,表單form經過
#              HTTP POST方法提交請求,可是表單中可能沒有數據,所以不能使用
#              if request.POST來判斷是否使用了HTTP POST 方法;應該使用  if request.method=="POST"
#
#
#
# COOKIES:     包含全部cookies的標準Python字典對象;keys和values都是字符串。
#
# FILES:      包含全部上傳文件的類字典對象;FILES中的每個Key都是<input type="file" name="" />
          標籤中 name屬性的值,FILES中的每個value同時也是一個標準的python字典對象,包含下面三個Keys: # # filename: 上傳文件名,用字符串表示 # content_type: 上傳文件的Content Type # content: 上傳文件的原始內容 # # # user: 是一個django.contrib.auth.models.User對象,表明當前登錄的用戶。若是訪問用戶當前 # 沒有登錄,user將被初始化爲django.contrib.auth.models.AnonymousUser的實例。你 # 能夠經過user的is_authenticated()方法來辨別用戶是否登錄: # if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware # 時該屬性纔可用 # # session: 惟一可讀寫的屬性,表明當前會話的字典對象;本身有激活Django中的session支持時該屬性纔可用。 #方法 get_full_path(), 好比:http://127.0.0.1:8000/index33/?name=123 ,req.get_full_path()獲得的結果就是/index33/?name=123 req.path:/index33

 

注意一個經常使用方法:request.POST.getlist('')  若是傳送後端的是列表要用POST.getlist()取值

2 HttpResponse對象:

  對於HttpRequest對象來講,是由django自動建立的,可是,HttpResponse對象就必須咱們本身建立。每一個view請求處理方法必須返回一個HttpResponse對象。

  HttpResponse類在django.http.HttpResponse

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

頁面渲染:         render(request,「HTML」)(推薦)<br>                 render_to_response(),
頁面跳轉:         redirect("路徑")
locals():    能夠直接將函數中全部的變量傳給模板

七 Template基礎 

模板系統介紹

模板系統的組成:HTML代碼和邏輯控制代碼

邏輯控制代碼能夠理解是django模板語言

django的模板語言組成

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

  2. 標籤(tag)的使用(使用大括號和百分比的組合來表示使用tag)
  3. 模板繼承

模板語言之變量

語法

1
{{var_name}}   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}))
View Code

Django 模板解析很是快捷。 大部分的解析工做都是在後臺經過對簡短正則表達式一次性調用來完成。 這和基於 XML 的模板引擎造成鮮明對比,那些引擎承擔了 XML 解析器的開銷,且每每比 Django 模板渲染引擎要慢上幾個數量級。

from django.shortcuts import render,HttpResponse
from django.template.loader import get_template #記得導入
# Create your views here.


import datetime
from django.template import Template,Context

# def current_time(req):
    #原始的視圖函數
    # now=datetime.datetime.now()
    # html="<html><body>如今時刻:<h1>%s.</h1></body></html>" %now
    # return HttpResponse(html)



# def current_time(req):

      #django模板修改的視圖函數
#     now=datetime.datetime.now()
#     t=Template('<html><body>如今時刻是:<h1 style="color:red">{{current_date}}</h1></body></html>')
      #t=get_template('current_datetime.html')
#     c=Context({'current_date':now})
#     html=t.render(c)
#     return HttpResponse(html)

#另外一種寫法(推薦)

def current_time(req):

    now=datetime.datetime.now()

    return render(req, 'current_datetime.html', {'current_date':now})

推薦方式

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

在到目前爲止的例子中,咱們經過 context 傳遞的簡單參數值主要是字符串,然而,模板系統可以很是簡潔地處理更加複雜的數據結構,例如list、dictionary和自定義的對象。

在 Django 模板中遍歷複雜數據結構的關鍵是句點字符 (.)。

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

>>> 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'

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

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

語法格式

{{var|filter:param}} 

管道符號後面的功能,好比{{ var|length }},求變量長度的 length 就是一個過濾器。

經常使用的過濾器

1.add          :   給變量加上相應的值
   
2 addslashes   :    給變量中的引號前加上斜線
  
3  capfirst     :    首字母大寫
  
4  cut          :   從字符串中移除指定的字符
  
5  date         :   格式化日期字符串
 
6  default      :   若是值是False,就替換成設置的默認值,不然就是用原本的值
 
7  default_if_none:  若是值是None,就替換成設置的默認值,不然就使用原本的值

標籤(tag)的使用

語法格式

{% tags %}

{% if %} 的使用

{% if %} 和 {% endif %}要成對

{% 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 %}

{% for %}不支持中斷循環,也不支持continue語句

{% for %}關於循環其餘用法

forloop.counter表示循環的次數,它從1開始計數,第一次循環設爲1:
forloop.counter0    索引從 0 開始算
forloop.revcounter表示循環中剩下的items數量,第一次循環時設爲items總數,最後一次設爲1
forloop.revcounter0表示`items總數少一個,最後一次循環設置爲0
forloop.first表示當第一次循環時值爲True,在特別狀況下頗有用:
forloop.last表示當最後一次循環時值爲True
forloop.parentioop表示在嵌套循環中表示父級循環的forloop

富有魔力的forloop變量只能在循環中獲得,當模板解析器到達{% endfor %}時forloop就消失了

若是你的模板context已經包含一個叫forloop的變量,Django會用{% for %}標籤替代它

Django會在for標籤的塊中覆蓋你定義的forloop變量的值

在其餘非循環的地方,你的forloop變量仍然可用

{% for item in todo_list %}
        <p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}
表示循環的次數,它從1開始計數,第一次循環設爲1:

{%csrf_token%}:csrf_token標籤

用於生成csrf_token的標籤,用於防治跨站攻擊驗證。注意若是你在view的index裏用的是render_to_response方法,不會生效

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

<form action="{% url "路由別名"%}" >
          <input type="text">
          <input type="submit"value="提交">
          {%csrf_token%}
</form>

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

{% with total=fhjsaldfhjsdfhlasdfhljsdal %} {{ total }} {% endwith %}
基本不多起復雜變量名,通常起變量名都要特變形象

{% verbatim %}: 禁止render渲染  

{% verbatim %}
         {{ hello }}
{% endverbatim %
 
 
若是想要{{hello}}在網頁正常顯示出來,則用這個

{% load %}: 加載標籤庫 

靜態文件的引入方式用過

{% load  staticfiles %}

後面引入其餘的標籤庫在一一列出

自定義filter和simple_tag

咱們自定義過濾器和簡單的標籤咱們須要

  1. 在app中建立templatetags文件夾(文件夾名字必須的是這個)
  2. 建立任意 .py 文件,如:my_tags.py
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from django import template
from django.utils.safestring import mark_safe
register = template.Library()  #register的名字是固定的,不可改變
 
@register.filter
def filter_multi(x,y):
    return x*y
 
@register.simple_tag
def simple_tag_multi(x,y):
    return x*y
 
@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg)
    return mark_safe(result)

如何調用自定義filter和simple_tag

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

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

{% load my_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ num|filter_multi:2 }} #24 <br>
 
{{ num|filter_multi:"[22,333,4444]" }}<br>
 
 
<p>{% simple_tag_multi 2 5 %}  參數不限,但不能放在if for語句中 </p>
{% simple_tag_multi num 5 %}
 
</body>
</html> 

視圖和路由的配置文件  

#路由
from django.conf.urls import url
from django.contrib import admin
from app01 import views
 
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/',views.index),
]
 
 
#視圖
 
from django.shortcuts import render,HttpResponse
 
# Create your views here.
def index(request):
 
    num=12
    return  render(request,"index.html",locals()) 

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

模板引入和繼承

模板引入

 {% include %}該標籤容許在(模板中)包含其它的模板的內容。 標籤的參數是所要包含的模板名稱,能夠是一個變量,也能夠是用單/雙引號硬編碼的字符串。 每當在多個模板中出現相同的代碼時,就應該考慮是否要使用 {% include %} 來減小重複。

引入方法

{% load staticfiles %}
 
HTML相關內容
 
 
{% include '要引入的html文件名' %}

模板繼承 

 常見的 Web 開發問題: 在整個網站中,如何減小共用頁面區域(好比站點導航)所引發的重複和冗餘代碼?

解決該問題的傳統作法是使用 服務器端的 includes ,你能夠在 HTML 頁面中使用該指令將一個網頁嵌入到另外一箇中。 事實上, Django 經過剛纔講述的 {% include %} 支持了這種方法。 可是用 Django 解決此類問題的首選方法是使用更加優雅的策略—— 模板繼承 。

本質上來講,模板繼承就是先構造一個基礎框架模板,然後在其子模板中對它所包含站點公用部分和定義塊進行重載  

若是子板不自定義塊,默認會繼承母板的全部內容(包括模板的css,js),若是子板要修改css或js文件,在相應地方加塊,就能夠了

例如:

簡單寫一個子板繼承母板

定義母板文件base.html,定義子板要自定義的塊

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
 
<H1> HAHA </H1>
 
{% block  content %}
    <h2>子板自定義修改的內容</h2>
 
{% endblock %}
</body>
</html> 

定義子板文件child.html  

{% extends "base.html" %} 

子板若是就這麼一行代碼,就會繼承母板的全部內容,這{% extends "母板文件" %}必須寫在最首行 

 若是要自定義修改塊

{% extends "base.html" %}
{% block content %}
    <h2 style="color: red">我是子板,修改了母板自定義塊的內容</h2>
{% endblock %} 

注:

母板

{% block 自定義塊名%}   

 

子板的塊

{% block 母板中相應設置的塊名 }

 

{% block %}  內容 {% endblock %}的標籤也是成對出現  

使用繼承的注意事項:

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

模板繼承的一些訣竅:

  1. 若是在模板中使用 {% extends %} ,必須保證其爲模板中的第一個模板標記。 不然,模板繼承將不起做用。
  2. 通常來講,基礎模板中的 {% block %} 標籤越多越好。 記住,子模板沒必要定義父模板中全部的代碼塊,所以你能夠用合理的缺省值對一些代碼塊進行填充,而後只對子模板所需的代碼塊進行(重)定義。 俗話說,鉤子越多越好。
  3. 若是發覺本身在多個模板之間拷貝代碼,你應該考慮將該代碼段放置到父模板的某個 {% block %} 中。若是你須要訪問父模板中的塊的內容,使用 {{ block.super }}這個標籤吧,這一個魔法變量將會表現出父模板中的內容。 若是隻想在上級代碼塊基礎上添加內容,而不是所有重載,該變量就顯得很是有用了。
  4. 不容許在同一個模板中定義多個同名的 {% block %} 。 存在這樣的限制是由於block 標籤的工做方式是雙向的。也就是說,block 標籤不只挖了一個要填的坑,也定義了在父模板中這個坑所填充的內容。若是模板中出現了兩個相同名稱的 {% block %} 標籤,父模板將無從得知要使用哪一個塊的內容。

8、Model層

一、基本建立

Django提供了一個抽象層("Model")的構建和管理Web應用程序的數據。

Django使用一種新的方式,即:關係對象映射(Object Relational Mapping,簡稱ORM)。

  • 每一個模型是一個Python類,子類django.db.models.model
  • 模型中的每一個屬性表明一個數據庫字段。
# DEMO

class Student(models.Model):
    name = models.CharField(max_length=10)
    sex = models.CharField(max_length=10)
    age = models.IntegerField()
    grade = models.ForeignKey('Grade')
  1 AutoField(Field)
  2         - int自增列,必須填入參數 primary_key=True
  3 
  4     BigAutoField(AutoField)
  5         - bigint自增列,必須填入參數 primary_key=True
  6 
  7         注:當model中若是沒有自增列,則自動會建立一個列名爲id的列
  8         from django.db import models
  9 
 10         class UserInfo(models.Model):
 11             # 自動建立一個列名爲id的且爲自增的整數列
 12             username = models.CharField(max_length=32)
 13 
 14         class Group(models.Model):
 15             # 自定義自增列
 16             nid = models.AutoField(primary_key=True)
 17             name = models.CharField(max_length=32)
 18 
 19     SmallIntegerField(IntegerField):
 20         - 小整數 -3276832767
 21 
 22     PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
 23         - 正小整數 032767
 24     IntegerField(Field)
 25         - 整數列(有符號的) -21474836482147483647
 26 
 27     PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
 28         - 正整數 02147483647
 29 
 30     BigIntegerField(IntegerField):
 31         - 長整型(有符號的) -92233720368547758089223372036854775807
 32 
 33     自定義無符號整數字段
 34 
 35         class UnsignedIntegerField(models.IntegerField):
 36             def db_type(self, connection):
 37                 return 'integer UNSIGNED'
 38 
 39         PS: 返回值爲字段在數據庫中的屬性,Django字段默認的值爲:
 40             'AutoField': 'integer AUTO_INCREMENT',
 41             'BigAutoField': 'bigint AUTO_INCREMENT',
 42             'BinaryField': 'longblob',
 43             'BooleanField': 'bool',
 44             'CharField': 'varchar(%(max_length)s)',
 45             'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
 46             'DateField': 'date',
 47             'DateTimeField': 'datetime',
 48             'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
 49             'DurationField': 'bigint',
 50             'FileField': 'varchar(%(max_length)s)',
 51             'FilePathField': 'varchar(%(max_length)s)',
 52             'FloatField': 'double precision',
 53             'IntegerField': 'integer',
 54             'BigIntegerField': 'bigint',
 55             'IPAddressField': 'char(15)',
 56             'GenericIPAddressField': 'char(39)',
 57             'NullBooleanField': 'bool',
 58             'OneToOneField': 'integer',
 59             'PositiveIntegerField': 'integer UNSIGNED',
 60             'PositiveSmallIntegerField': 'smallint UNSIGNED',
 61             'SlugField': 'varchar(%(max_length)s)',
 62             'SmallIntegerField': 'smallint',
 63             'TextField': 'longtext',
 64             'TimeField': 'time',
 65             'UUIDField': 'char(32)',
 66 
 67     BooleanField(Field)
 68         - 布爾值類型
 69 
 70     NullBooleanField(Field):
 71         - 能夠爲空的布爾值
 72 
 73     CharField(Field)
 74         - 字符類型
 75         - 必須提供max_length參數, max_length表示字符長度
 76 
 77     TextField(Field)
 78         - 文本類型
 79 
 80     EmailField(CharField):
 81         - 字符串類型,Django Admin以及ModelForm中提供驗證機制
 82 
 83     IPAddressField(Field)
 84         - 字符串類型,Django Admin以及ModelForm中提供驗證 IPV4 機制
 85 
 86     GenericIPAddressField(Field)
 87         - 字符串類型,Django Admin以及ModelForm中提供驗證 Ipv4和Ipv6
 88         - 參數:
 89             protocol,用於指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
 90             unpack_ipv4, 若是指定爲True,則輸入::ffff:192.0.2.1時候,可解析爲192.0.2.1,開啓刺功能,須要protocol="both"
 91 
 92     URLField(CharField)
 93         - 字符串類型,Django Admin以及ModelForm中提供驗證 URL
 94 
 95     SlugField(CharField)
 96         - 字符串類型,Django Admin以及ModelForm中提供驗證支持 字母、數字、下劃線、鏈接符(減號)
 97 
 98     CommaSeparatedIntegerField(CharField)
 99         - 字符串類型,格式必須爲逗號分割的數字
100 
101     UUIDField(Field)
102         - 字符串類型,Django Admin以及ModelForm中提供對UUID格式的驗證
103 
104     FilePathField(Field)
105         - 字符串,Django Admin以及ModelForm中提供讀取文件夾下文件的功能
106         - 參數:
107                 path,                      文件夾路徑
108                 match=None,                正則匹配
109                 recursive=False,           遞歸下面的文件夾
110                 allow_files=True,          容許文件
111                 allow_folders=False,       容許文件夾
112 
113     FileField(Field)
114         - 字符串,路徑保存在數據庫,文件上傳到指定目錄
115         - 參數:
116             upload_to = ""      上傳文件的保存路徑
117             storage = None      存儲組件,默認django.core.files.storage.FileSystemStorage
118 
119     ImageField(FileField)
120         - 字符串,路徑保存在數據庫,文件上傳到指定目錄
121         - 參數:
122             upload_to = ""      上傳文件的保存路徑
123             storage = None      存儲組件,默認django.core.files.storage.FileSystemStorage
124             width_field=None,   上傳圖片的高度保存的數據庫字段名(字符串)
125             height_field=None   上傳圖片的寬度保存的數據庫字段名(字符串)
126 
127     DateTimeField(DateField)
128         - 日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
129 
130     DateField(DateTimeCheckMixin, Field)
131         - 日期格式      YYYY-MM-DD
132 
133     TimeField(DateTimeCheckMixin, Field)
134         - 時間格式      HH:MM[:ss[.uuuuuu]]
135 
136     DurationField(Field)
137         - 長整數,時間間隔,數據庫中按照bigint存儲,ORM中獲取的值爲datetime.timedelta類型
138 
139     FloatField(Field)
140         - 浮點型
141 
142     DecimalField(Field)
143         - 10進制小數
144         - 參數:
145             max_digits,小數總長度
146             decimal_places,小數位長度
147 
148     BinaryField(Field)
149         - 二進制類
150 
151 字段
字段
 1 null                數據庫中字段是否能夠爲空
 2     db_column           數據庫中字段的列名
 3     db_tablespace
 4     default             數據庫中字段的默認值
 5     primary_key         數據庫中字段是否爲主鍵
 6     db_index            數據庫中字段是否能夠創建索引
 7     unique              數據庫中字段是否能夠創建惟一索引
 8     unique_for_date     數據庫中字段【日期】部分是否能夠創建惟一索引
 9     unique_for_month    數據庫中字段【月】部分是否能夠創建惟一索引
10     unique_for_year     數據庫中字段【年】部分是否能夠創建惟一索引
11 
12     verbose_name        Admin中顯示的字段名稱
13     blank               Admin中是否容許用戶輸入爲空
14     editable            Admin中是否能夠編輯
15     help_text           Admin中該字段的提示信息
16     choices             Admin中顯示選擇框的內容,用不變更的數據放在內存中從而避免跨表操做
17                         如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)
18 
19     error_messages      自定義錯誤信息(字典類型),從而定製想要顯示的錯誤信息;
20                         字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
21                         如:{'null': "不能爲空.", 'invalid': '格式錯誤'}
22 
23     validators          自定義錯誤驗證(列表類型),從而定製想要的驗證規則
24                         from django.core.validators import RegexValidator
25                         from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
26                         MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
27                         如:
28                             test = models.CharField(
29                                 max_length=32,
30                                 error_messages={
31                                     'c1': '優先錯信息1',
32                                     'c2': '優先錯信息2',
33                                     'c3': '優先錯信息3',
34                                 },
35                                 validators=[
36                                     RegexValidator(regex='root_\d+', message='錯誤了', code='c1'),
37                                     RegexValidator(regex='root_112233\d+', message='又錯誤了', code='c2'),
38                                     EmailValidator(message='又錯誤了', code='c3'), ]
39                             )
40 
41 參數
42 
43 Field參數
field參數

二、連表結構例如在建表的時候應該瞭解到如何

  • 一對多:models.ForeignKey(其餘表)
  • 多對多:models.ManyToManyField(其餘表)
  • 一對一:models.OneToOneField(其餘表)
  • 應用場景:

    • 一對多:當一張表中建立一行數據時,有一個單選的下拉框(能夠被重複選擇)
      例如:建立用戶信息時候,須要選擇一個用戶類型【普通用戶】【金牌用戶】【鉑金用戶】等。
    • 多對多:在某表中建立一行數據是,有一個能夠多選的下拉框
      例如:建立用戶信息,須要爲用戶指定多個愛好
    • 一對一:在某表中建立一行數據時,有一個單選的下拉框(下拉框中的內容被用過一次就消失了
      例如:原有含10列數據的一張表保存相關信息,通過一段時間以後,10列沒法知足需求,須要爲原來的表再添加5列數據

三、表操做

a、基本操做

# 增
    #
    # models.Tb1.objects.create(c1='xx', c2='oo')  增長一條數據,能夠接受字典類型數據 **kwargs

    # obj = models.Tb1(c1='xx', c2='oo')
    # obj.save()

# 查
    #
    # models.Tb1.objects.get(id=123)         # 獲取單條數據,不存在則報錯(不建議)
    # models.Tb1.objects.all()               # 獲取所有
    # models.Tb1.objects.filter(name='seven')# 獲取指定條件的數據

# 刪
    #
    # models.Tb1.objects.filter(name='seven').delete() # 刪除指定條件的數據

# 改
    # models.Tb1.objects.filter(name='seven').update(gender='0')  # 將指定條件的數據更新,均支持 **kwargs
    # obj = models.Tb1.objects.get(id=1)
    # obj.c1 = '111'
    # obj.save() 

b、進階操做(了不得的雙下劃線)  

 # 獲取個數
        #
        # models.Tb1.objects.filter(name='seven').count()

        # 大於,小於
        #
        # models.Tb1.objects.filter(id__gt=1)              # 獲取id大於1的值
        # models.Tb1.objects.filter(id__gte=1)             # 獲取id大於等於1的值
        # models.Tb1.objects.filter(id__lt=10)             # 獲取id小於10的值
        # models.Tb1.objects.filter(id__lte=10)            # 獲取id小於10的值
        # models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 獲取id大於1 且 小於10的值

        # in
        #
        # models.Tb1.objects.filter(id__in=[11, 22, 33])   # 獲取id等於十一、2二、33的數據
        # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in

        # isnull
        # Entry.objects.filter(pub_date__isnull=True)

        # contains
        #
        # models.Tb1.objects.filter(name__contains="ven")
        # models.Tb1.objects.filter(name__icontains="ven")  # icontains大小寫不敏感
        # models.Tb1.objects.exclude(name__icontains="ven")

        # range
        #
        # models.Tb1.objects.filter(id__range=[1, 2])       # 範圍bettwen and

        # 其餘相似
        #
        # startswith,istartswith, endswith, iendswith,

        # order by
        #
        # models.Tb1.objects.filter(name='seven').order_by('id')    # asc
        # models.Tb1.objects.filter(name='seven').order_by('-id')   # desc

        # group by
        #
        # from django.db.models import Count, Min, Max, Sum
        # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
        # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

        # limit 、offset
        #
        # models.Tb1.objects.all()[10:20]

        # regex正則匹配,iregex 不區分大小寫
        #
        # Entry.objects.get(title__regex=r'^(An?|The) +')
        # Entry.objects.get(title__iregex=r'^(an?|the) +')

        # date
        #
        # Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
        # Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))

        # year
        #
        # Entry.objects.filter(pub_date__year=2005)
        # Entry.objects.filter(pub_date__year__gte=2005)

        # month
        #
        # Entry.objects.filter(pub_date__month=12)
        # Entry.objects.filter(pub_date__month__gte=6)

        # day
        #
        # Entry.objects.filter(pub_date__day=3)
        # Entry.objects.filter(pub_date__day__gte=3)

        # week_day
        #
        # Entry.objects.filter(pub_date__week_day=2)
        # Entry.objects.filter(pub_date__week_day__gte=2)

        # hour
        #
        # Event.objects.filter(timestamp__hour=23)
        # Event.objects.filter(time__hour=5)
        # Event.objects.filter(timestamp__hour__gte=12)

        # minute
        #
        # Event.objects.filter(timestamp__minute=29)
        # Event.objects.filter(time__minute=46)
        # Event.objects.filter(timestamp__minute__gte=29)

        # second
        #
        # Event.objects.filter(timestamp__second=31)
        # Event.objects.filter(time__second=2)
        # Event.objects.filter(timestamp__second__gte=31)

c、連表操做(了不得的雙下劃線)  

 1 # DEMO
 2 # 班級和老師存在多對多關係、班級和學生存在一對多關係
 3 from django.db import models
 4 
 5 class Classes(models.Model):
 6     titile = models.CharField(max_length=32)
 7     m = models.ManyToManyField('Teachers')
 8 
 9 
10 class Teachers(models.Model):
11     name = models.CharField (max_length=32)
12 
13 
14 class Student(models.Model):
15     username = models.CharField(max_length=32)
16     age = models.IntegerField()
17     gender = models.BooleanField()
18     cs = models.ForeignKey(Classes)
表結構
 1 # 增
 2 # Teachers.objects.create(name='root')
 3 # obj = Teachers(name='root')
 4 # obj.save()
 5 # 查
 6 # Teachers.objects.all()
 7 # Teachers.objects.filter(id=1)
 8 # Teachers.objects.filter(id=1,name='root')
 9 # result = Teachers.objects.filter(id__gt=1)
10 # [obj(id,name),]
11 # result = Teachers.objects.filter(id__gt=1).first()
12 # 刪
13 # Teachers.objects.filter(id=1).delete()
14 # 改
15 # Teachers.objects.all().update(name='alex')
16 # Teachers.objects.filter(id=1).update(name='alex')
單表操做
 1 # 增長
 2 # Student.objects.create(username='東北',age=18,gender='',cs_id=1)
 3 # Student.objects.create(username='東北',age=18,gender='',cs= Classes.objects.filter(id=1).first() )
 4 # 查看
 5 """
 6 ret = Student.objects.all()
 7 # []
 8 # [ obj(..),]
 9 # [ obj(1      東北       181),obj(2      東北1      1182),obj(..),]
10 for item in ret:
11     print(item.id)
12     print(item.username)
13     print(item.age)
14     print(item.gender)
15     print(item.cs_id)
16     print(item.cs.id)
17     print(item.cs.name)
18 """
19 # 刪除
20 # Student.objects.filter(id=1).delete()
21 # Student.objects.filter(cs_id=1).delete()
22 
23 # cid = input('請輸入班級ID')
24 # Student.objects.filter(cs_id=cid).delete()
25 
26 # cname = input('請輸入班級名稱')
27 # Student.objects.filter(cs_id=cid).delete()
28 # Student.objects.filter(cs__name=cname).delete()
一對多
 1 """
 2 班級:
 3 id  title
 4 1    3班
 5 2    4班
 6 3    5班
 7 老師:
 8 id   title
 9  1    Alex
10  2    老妖
11  3    瞎驢
12  4    Eric
13  老師班級關係表(類):
14 id   班級id   老師id
15  1     1        2
16  2     1        3
17  4     2        2
18  5     2        3
19  6     2        4
20  7     1        5
21 
22 
23 # 增
24 obj = Classes.objects.filter(id=1).first() #1    3班
25 obj.m.add(2)
26 obj.m.add([4,3])
27 
28 # obj = Classes.objects.filter(id=2).first() #1    3班
29 # obj.m.add(2)
30 # obj.m.add([4,3])
31 
32 obj = Classes.objects.filter(id=1).first() #1    3班
33 # 刪除
34 # obj.m.remove([4,3])
35 # 清空
36 obj.m.clear()
37 # 重置
38 obj.m.set([2,3,5])
39 
40 # 查第三張表
41 # 把3班的全部老師列舉
42 obj = Classes.objects.filter(id=1).frist()
43 obj.id
44 obj.titile
45 ret = obj.m.all() # 第三張表
46 # ret是一個 [ 老師1(id,name),obj(id,name)   ]
多對多

d、其它操做

 1 # extra
 2     #
 3     # extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
 4     #    Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
 5     #    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
 6     #    Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
 7     #    Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
 8 
 9     # F  使用查詢條件的值,專門取對象中某列值的操做
10     #
11     # from django.db.models import F
12     # models.Tb1.objects.update(num=F('num')+1)
13 
14 
15     # Q  與 或 非  的關係構建搜索條件
16     #
17     # 方式一:
18     # Q(nid__gt=10)
19     # Q(nid=8) | Q(nid__gt=10)
20     # Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
21     # 方式二:
22     # con = Q()
23     # q1 = Q()
24     # q1.connector = 'OR'
25     # q1.children.append(('id', 1))
26     # q1.children.append(('id', 10))
27     # q1.children.append(('id', 9))
28     # q2 = Q()
29     # q2.connector = 'OR'
30     # q2.children.append(('c1', 1))
31     # q2.children.append(('c1', 10))
32     # q2.children.append(('c1', 9))
33     # con.add(q1, 'AND')
34     # con.add(q2, 'AND')
35     #
36     # models.Tb1.objects.filter(con)
37 
38 
39     # exists()方法來檢查是否有數據 exists()的檢查能夠避免數據放入queryset的cache。
40     # obj = Book.objects.filter(id=4)
41     # if obj.exists():print("hello world!")
42 
43     # 執行原生SQL
44     #
45     # from django.db import connection, connections
46     # cursor = connection.cursor()  # cursor = connections['default'].cursor()
47     # cursor.execute("""SELECT * from auth_user where id = %s""", [1])
48     # row = cursor.fetchone()
49 
50 Q、F、exists()
Q和F

e、補充

    # values             取到的是字典集合
    # values_list        取到的是沒有鍵的元祖形式

    # get                只有在能取到一條數據的時候纔不會報錯(不推薦)
    # filter([篩選條件])
    # all()              倆者取到的都是Query set集合對象 是可迭代、可切片、索引取值

    # iterator()         ORM的惰性機制
                         # Publisher.objects.all()或者.filter()等都只是返回了一個QuerySet
                         # 並不會立刻執行sql,而是當調用QuerySet的時候才執行。
e、補充
相關文章
相關標籤/搜索