Django總結一

HTTPRequest與HTTPresponse

1、

1、互聯網兩臺機器之間通行:ip、端口、協議
    - 協議
        - HTTP  (80- HTTPS  (443) 

2、瀏覽器輸入URL一回車返回頁面發生了什麼?
    - 域名 -> DNS解析 -->ip地址 -> 找到服務端 ->服務端返回消息 -> 瀏覽器
    - 瀏覽器 <-> 服務器
    - 服務器把 寫好的HTML頁面,返回給瀏覽器,瀏覽器按照HTML格式渲染
    「

    」

3、請求和相應
    - HTTP協議的特色:
        - 瀏覽器給服務端發消息的過程叫請求(request)
        - 服務器給瀏覽器回覆消息的過程叫響應(response)
        
    - 請求和相應的消息都必須遵循一個固定的格式

4、python中Web框架分類
    - a、收發socket消息,按照HTTP協議解析消息   Web服務程序 wsgiref(模塊)、gunicorn、uWSGI
    - b、字符串替換,用來實現動態網頁                                
    - c、業務邏輯處理                            Web應用程序

    1- 本身實現abc的
        - Tronado  
    2- 本身實現bc使用別人的a
        - Django
    3- 本身實現c使用別人的ab
        - Flask
五、Web服務程序  <-  WSGI協議  -> Web應用程序


5.5、Django版本
    - LTS版本 (Long Team support)

6、建立第一個Django項目
    
    安裝:  pip install django==1.11.11
            pip install django==1.11.11 -i 指定源 

    - 一、命令行  Django-admin startproject first_Django
    - 2、Pycharm建立
        - file -> new Project ->右側選Django -> 選好路徑 ->選好環境 -> 名字app -> 在新的窗口打開文件
    - 3、啓動項目
        - 命令行啓動(切換到項目的根目錄)
            - python manage.py runserver 127.0.0.1:8090(改端口這樣指定)
        - pycharm啓動
            - 框中選項爲項目名->讓後點擊啓動按鈕(右上角)(若是想改就在旁邊點編輯-就能夠改端口等)

    - 目錄介紹
        - 和項目名同樣的是根目錄
        - 
    ---------------------
    - 先來一份本身的理解
        - 1、(與咱們所建立文件名一致的目錄)根目錄
            - manage.py 
                - 這是啓動文件,程序入口。
            - settings.py
                - 包含了項目的一些設置,包括數據庫信息、調試標誌以及其餘的一些工做的變量。
                - BASE_DIR = 項目的根目錄
                - TIMELATES = templates去哪找
                - DATABASES = 數據庫
                - 靜態文件配置
                    - STATIC_URL = '/static/' # 請別名
                    - STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),] # 配置去static下找靜態文件
            - urls.py
                - 路徑與視圖函數的映射關係


        - 二、templates - 這個文件夾存放的是HTML文件
        - 三、static - 這個文件夾是存放靜態文件,須要本身配置,用的時候的導入時用 
             /static/.. 來引入所用的靜態文件
                 # Static files (CSS, JavaScript, Images)
                # https://docs.djangoproject.com/en/1.11/howto/static-files/

                # 這個static就表明了下面的路徑 (尋找的時候就是去static下面的路徑中挨個找)
                STATIC_URL = '/static/'  # 起別名, HTML中找靜態文件都要以這個別名開始  (找到別名後就去這個別名的配置比文件中找對應的文件)

                # 這個常量是固定格式
                STATICFILES_DIRS = [
                    os.path.join(BASE_DIR, 'static'),
                ]
    
7、項目流程
    - 先輸入url
    - 去Django的urls中匹配urlpatterns->匹配上調用後面匹配的函數->去找對應的函數
    - 找到執行的函數->Django調用要執行的函數給函數傳一個request參數,全部和請求相關的數據 都在request中
    - render去templates文件夾找到HTML文件,打開讀取內容,按照http響應格式給瀏覽器返回讀取的內容
    - 瀏覽器收到Django返回的響應消息,按照HTML格式顯示這個消息



其餘:
    - from django.shortcuts import HttpResponse, render
        - HttpResponse (封裝了協議頭等-有待商議)
        - render (渲染)

    - 文件的上傳(form表單的提交, 必須用POST)
        def index(request):
            print(request.GET)
            print(request.POST)
            print(request.FILES)

            for item in request.FILES:
                fileobj = request.FILES.get(item)
                f = open('upload/%s' % fileobj.name, 'wb')
                item_file = fileobj.chunks()
                for line in item_file:
                    f.write(line)
                f.close()

            return HttpResponse("成功")
     - form表單上傳文件時須要注意的事情
         - action 最後加 /  或者 修改settings:APPEND_SLASH=False
         - method 必須爲post 
         - enctype = 「multipart/form-data」 必須寫

     - 指定IP登陸
         默認IP和端口
            python manage.py runserver
        指定端口:
            python manage.py runserver 192.168.12.12:8080
        此時會報錯,咱們須要修改配置文件:
        修改settings.py,將192.168.12.12添加到ALLOWED_HOSTS中
        ALLOWED_HOSTS=['172.31.169.182','127.0.0.1','192.168.1.50','192.168.1.115']
        也能夠將ALLOWED_HOSTS改爲通配符 *
        ALLOWED_HOSTS = ["*"]



2、

1、表單的提交(登陸)
    - submit -> action -> 對應函數(參數request(數據信息))-> 處理
        注意:必需要有name屬性 *****
    - 提交到服務器的是QueryDict對象,能夠經過get獲取值


2、form表單提交的三個要素
    - form標籤必須有action和method屬性
    - 全部獲取用戶輸入的標籤必須放在form表單中,必須有name屬性(input,select,textarea)
    - 必須有submit按鈕


3、redirect 跳轉,改變方向
    - 跳轉到別人的頁面,本身的頁面
        - 跳轉比人頁面
            redirect("https://baidu.com")
        - 跳轉本身頁面
            redirect("/相對路徑/")

四、Django必會三件套  from django.shortcuts import
    - HttpRequest    返回一個指定的字符串    
        (把字符串轉爲而二進制,而後按照HTTP響應格式要求返回)
    - render           返回一個HTML文件        HTML文件 模板語言
        (第一個參數爲request, 第二個參數爲render的頁面,第三個參數爲字典,將render頁面中的特殊符號替換{字典的鍵爲html的變量,值爲給頁面展現的值})
    - redirect        跳轉           路徑     URL
        (redirect(/index/) -> 在同網站不一樣地址間跳轉(返回重定向響應)
          redirect('https://wwww.baidu.com') -> 訪問指定的網址)

5、request相關屬性 (全部和請求相關的數據都封裝在request對象中)
    - POST      取到POST提交的數據(form表單提交的)
    - GET         取到URL攜帶的參數
    - method    當前此次請求的方法(GET/POST)

6、Django的模板語言
    {{ 變量 }}

7、Django項目project
    - app(應用) -> 不一樣的功能放在不一樣的app中
        - 命令 :
            - 建立app  
                python manage.py startapp app01(應用名)    
            - 註冊app(告訴Django建立了app)
                在settings中的 INSTALLED_APPS 添加新建立的app(app名.apps.apps中的類)


8、程序連接mysql
    - 使用pymysql模塊
        - 導入pymysql
        - 建立連接
        - 獲取執行命令的遊標
        - 用遊標執行SQL語句
        - 獲取SQL語句的執行結果
        - 關閉遊標
        - 關閉連接

    - ORM - Object Relationship Mapping (對象關係映射)
    - 這時,建立一種工具 幫助咱們翻譯SQL語句(ORM - 面向對象的思想)
        - 優勢
            - 開發效率高
            - 開發不用直接寫SQL語句
        - 缺點
            - 執行效率低

    - 對應關係
        ORM         DB

        類            數據表
        屬性            字段
        對象            數據行



    - Django項目project
        - app(應用) -> 不一樣的功能放在不一樣的app中
            - 命令 :
                - 建立app  
                    python manage.py startapp app01(應用名)    
                - 告訴Django建立了app
                    在settings中的 INSTALLED_APPS 添加新建立的app(app名.apps.apps中的類)
    - Django中ORM使用
        - 用處:
            - 操做數據表
            - 操做數據行
        - 使用
            - 手動建立數據庫
            - 告訴Django連那個數據庫
                - settings中配置DATABASES
                DATABASES = {
                    'default': {
                        'ENGINE': 'django.db.backends.mysql',  # 連接數據庫的類型
                        'NAME': 'db',  # 連接數據庫的名字
                        'HOST': '127.0.0.1',  # 數據庫主機地址
                        'PORT': 3306,  # 數據庫端口
                        'USER': 'root',  # 數據庫用戶名
                        'PASSWORD': '123456',  # 數據庫密碼
                    }
                }

            - 用什麼連接數據庫?
                - 利用第三方包 pymysql 和 MySQLdb(py2中)
                - 告訴Django用pymysql模塊代替默認的MySQLdb連接MySQL數據庫
                    和settings.py同級的__init__.py文件,寫上
                    import pymysql
                    pymysql.install_as_MySQLdb()

            - 在app/models.py的文件中建立類
                類必須繼承models.Model


            - 兩個命令
                - python manage.py makemigrations -> 生成腳本文件存放在app文件夾應用下的migrations文件夾中(至關於拿個小本本把models.py的變動記錄下來)
                - python manage.py migrate -> 把上面的變動記錄翻譯成sql語句,去數據庫執行

            - ORM查詢
                modules.User.object.filter(email='', pwd='')


3、

1、圖書管理系統
    - 出版社
        id name
    - 做者
        id name
    - 書
        id title 出版社_id
    - 書_做者關係表
        id 書_id 做者_id

2.ORM增刪改查
    models.表名.object./filter()/all()/create()
        - filter()  按照指定內容篩選 (字段=值)                放回一個列表
        - all()        查詢出數據庫全部信息(屬性order_by(id)排序) 返回一個列表
        - create()    向數據庫添加信息 (字段=值)建立一個對象        返回一個建立的對象
        - get()        返回一個對象
        - filter(id='').delete()    刪除
        - obj = 類名.object.get(id='')
            obj.name = '新值'     修改對象的屬性(修改數據行某個字段的值)
            obj.save()            把修改同步到數據庫

3、模板語言
    - for循環
        {% for i in ret %}
            {{ i }}
            {{ forloop.counter }}      for循環從1開始計數
            {{ forloop.counter0 }}    for循環從0開始計數
        {% endfor %}


總結:ORM的 查、增、刪、改

    -- client
            - 有一個展現頁面(xxx_show.html)
                - 這一個頁面一輸入執行後,get請求向server端發送
            - 這個展現頁面有添加按鈕、刪除按鈕、編輯按鈕
            - 這個頁面要展現內容
                - 是server端收到第一次的get請求而作出的response
                - 頁面須要用到模板語言for循環
                    {% for i in result %}
                        {{ i.xx }}  #獲取result中的每一個值(也就是server端傳來的東西) 
                    {% endfor %}
        - server
            - 首先會收到一開始訪問頁面的GET請求
            - 收到請求後到urls中找匹配的url,找到對應的url後,執行後面所對應的視圖函數
            - 找到對應的視圖函數後就行執行響應的邏輯,也就是拿出數據庫中的東西,發送給server
                - 能夠經過 models.表名.objects.all() 獲取數據庫這張表中的全部內容(返回一個列表)
                    - data = models.表名.objects.all()
                - 拿到數據後將這些數據給展現(經過render方法)
                    - return render(request, 'xxx_show.html', 'result':data)
                     #這裏的result就是要傳給xxx_show.html的一個變量(其中的值就是data的數據)

    -- client
            - 有一個展現頁面(xxx_show.html)
            - 這個頁面有一個添加按鈕(a標籤)
                - 點擊這個按鈕(a標籤),client會發送一個get請求,會用a標籤的路徑去訪問server
                - 這時會跳轉到a標籤所指的url(/add_xxx/)
                - 而後server給出response(這裏的業務邏輯就都得在server)
            - 第一次get請求server會返回一個add_xxx.html頁面
                - 這是能夠添加數據
                    - 用form表單,action爲add_xxx這個url,method爲post
                    - 點擊提交以後client向server發送一個請求
                    - server收到請求後回覆一個response

        - server
            - 收到a標籤跳轉的url(get請求響應)
            - 收到add_xxx這個url進入urls中匹配,匹配到就去他對應的視圖函數
            - 這個視圖函數處理響應的業務邏輯
                - 首先第一次來的時候時GET請求,這個時候應該將add_xxx.html這個頁面返回給client
                    - return render(request, add_xxx.html)
                - 而後server收到提交的POST請求
                    - 從POST請求中拿出client發送來的數據
                        - data = request.POST.get("input標籤的name")
                    - 將數據存入數據庫
                        - models.tablename.objects.create(字段=data)
                    - 將數據庫中的結果從新返回(也就是xxx_show。html)
                        - return redirect('/xxx_show/')

    -- client
            - 有一個展現頁面(xxx_show.html)
            - 有一個刪除按鈕(a標籤)
                - 點擊這個按鈕(a標籤),client會發送一個get請求,會用a標籤的路徑去訪問server
                - 點擊這個a標籤(按鈕)會跳轉到他對應的url('/del_xxx/')
                    - 這時須要將這個按鈕對應的數據傳到server,server才能按照這個數據去刪除
                    - <a href="/del_xxx/?id={{ i.id }}"><button>del</button></a>
                        - ?是一個固定格式,然後面就是一些參數(服務端要用的一些參數)
                        - server收到這個參數後就能夠按照他進行相應的操做
                - 而後server會返回一個response(這裏的業務邏輯在server端)

        - server
            - 收到a標籤跳轉的url(get請求響應)
            - 收到del_xxx這個url進入urls中匹配,匹配到就去他對應的視圖函數
            - 這個視圖函數處理響應的業務邏輯
                - 經過client傳來的參數來鎖定刪除的id
                    - del_id = request.GET.get("id")
                - 刪除數據庫中del_id對應的值
                    - models.tablename.objects.fileter(id=del_id).delete()
                - 刪除成功後返回刪除後的頁面('/xxx_show/')(重定性)
                    - return redirect('/xxx_show/')

    -- client
            - 有一個展現頁面(xxx_show.html)
            - 有一個編輯(edit)按鈕(a標籤)
                - 點擊這個按鈕(a標籤),client會發送一個get請求,會用a標籤的路徑去訪問server
                - 點擊這個a標籤(按鈕)會跳轉到他對應的url('/edit_xxx/')
                    - 這時須要將這個按鈕對應的數據傳到server,server才能更改這個數據
                    - <a href="/edit_xxx/?id={{ i.id }}"><button>del</button></a>
                        - ?是一個固定格式,然後面就是一些參數(服務端要用的一些參數)
                        - server收到這個參數後就能夠按照他進行相應的操做
                - 而後server會返回一個response(這裏的業務邏輯在server端)
            - 第一次發送get請求時會跳轉到edit_xxx.html這個頁面,這裏面是該行對應的數據
            - 第二次發送post請求,這裏面會有修改後的數據而後發送給server處理
                -     <form action="/edit_press/?id={{ result.id }}" method="post">
                        <input type="text" name="updata_name" value="{{ result.name }}">
                        <input type="submit">
                    </form>

                    - input中的數據都是在server查出的數據展示出來的
                    - id是經過點擊edit按鈕的時候將這個按鈕對應的id值記錄了下來

                - 處理完後返回原來的xxx_show


        - server
            - 收到a標籤跳轉的url(get請求響應)
            - 收到edit_xxx這個url進入urls中匹配,匹配到就去他對應的視圖函數
            - 這個視圖函數處理響應的業務邏輯
                - 第一遍的GET請求
                    - 經過client傳來的參數來鎖定編輯(edit)的id
                        - edit_id = request.GET.get("id")
                    - 會返回當前編輯行的內容
                        - 從數據庫中拿出這個值,將這個值展示在edit_xxx.html頁面中
                            - result = models.tablename.objects.filter(id="")[0]
                    - 返回當前編輯的頁面
                        - return render(request, 'edit_xxx.html', {'resule': result})

                - 第二遍請求是提交數據後的POST請求,
                    - form表單中的action爲這個編輯頁面,
                    - 這個頁面後面的參數爲第一次get請求獲得的數據
                    - 能夠經過GET方法來獲取URL上的參數的值

                    - 這個時候form表單對應的url來urls中找對應的視圖函數
                        - 這個視圖函數就會執行POST請求的邏輯
                        - 用這個新數據把數據庫中的舊數據掩蓋
                            - 獲取更改後的值
                                - data = request.POST.get("updata_name")
                            - 更改數據庫中的值
                                - 從數據庫找到id對應的對象
                                - #這裏的id就是第一次點擊編輯的時候獲得的id值(--對應的)
                                - new_obj = models.tablename.objects.filter(id='edit_id')[0]
                                - new_obj.name = data  #將新的值賦值給數據庫中的變量
                                - new_obj.save()  #這個事務必須save數據庫中的數據纔會更改

                            - 更改完成後返回,xxx_show頁面
                                - return redirect('/xxx_show/')



    注意:
        經過GET來獲取URL中的值(和請求無關),POST獲取表單提交的值。




4、

1、 a標籤
    - href屬性
        - 相對路徑
        - 絕對路徑
    - target = "_blank" 跳轉到新頁面, 不寫默認覆蓋本身的頁面
    - 錨點(同網站標籤的跳轉(#id名))

2# 出版社
class Press(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)

    def __str__(self):  # print的時候測試使用
        return self.name


#
class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    # Django1.1默認就是級聯刪除,2.0必須指定
    # 能夠經過字符串的反射找Press,若是在代碼前面就能夠直接用,to=關聯的表名
    # 外鍵字段ORM會給他默認加一個_id (加上_id後他的值就是對應關聯表的主鍵值)
    press = models.ForeignKey(to='Press', on_delete=models.CASCADE)
    

- 一對多
    - 一個出版社對應多本書(外鍵設置在多的一方)
        - 書的屬性有一個外鍵爲連接出版社的press_id

書籍的增刪改查
    ---- 查

注意:
    - 增的時候,出版社就是表中的固定出版社,用一個select標籤將數據展現,而不是用戶本身填
        <form action="/add_book/" method="post">
          書名:<input type="text" name="book_title">
          <select name="title_name" id="">
            {% for press in data %}
                <option value="{{ press.id }}">
                    {{ press.name }}
                </option>
            {% endfor %}
          </select>
          <input type="submit">
       </form>
    - 改的實時,出版社的內容須要先選定好。須要用模板語言來判斷
        # 這中狀況form表單不指定action他默認會提交當前的頁面(這是的頁面是點擊編輯時的頁面)
        <form action="/edit_book/?id={{ data.id }}" method="post">
            <input type="text" name="title_name" value="{{ data.title }}">
            <select name="press_name" id="">
                {% for press in data_list %}
                    {% if data.press == press %}
                        <option value="{{ press.id }}" selected>
                        </option>
                            {{ press.name }}
                        {% else %}
                        <option value="{{ press.id }}">
                            {{ press.name }}
                        </option>
                    {% endif %}
                {% endfor %}
            </select>
            <input type="submit">
        </form>


5、
    - 給數據庫中已經存在的表添加另一個字段,ORM不知道如何處理
        - 1) 輸入 1 會讓用戶本身填寫一個默認值(在命令行中)
        - 2) 輸入 2 本身在ORMclass中指定字段本身加默認值(退出命令行)在modules中修改
                - null = True
                - default = 默認值


1. 多對多關係    
        做者   <-->  書籍
        1. 表結構設計
            1. SQL版
                -- 建立做者表
                create table author(
                    id int primary key auto_increment,
                    name varchar(32) not null
                );
                
                -- 建立做者和書的關係表
                create table author2book(
                    id int primary key auto_increment,
                    author_id int not null,
                    book_id int not null,
                    constraint fk_author foreign key (author_id) references author(id) on delete cascade on update cascade,
                    constraint fk_book foreign key (book_id) references book(id) on delete cascade on update cascade
                );

            2. ORM版
                1. 初版:
                    本身建立第三張表
                2. 第二版
                    讓ORM幫咱們建立第三張表
                    models.ManyToManyField()
                3. 第三版
                    待補充...(ORM進階操做的時候)            
    2. 做者的增刪改查
        1. 查詢
            author_obj.books        --> 獲得的只是一個關聯關係,並不能拿到數據
            author_obj.books.all()  --> 獲得和我這個做者關聯的全部書籍對象列表
        2. 添加
            1. getlist() # 獲得同一name的列表對象
            2. add()
            3. set()
            
        3. 刪除
        
        4. 編輯
            1. 模板語言中
                {% if book in author.books.all %}
            2. ORM編輯多對多
                1. 不能直接操做第三張關係表
                2. 藉助ORM給提供的方法
                    1. all()
                    2. add(id1,id2)
                    3. set([id1, id2])
                    4. clear()
    3. Django模板語言
        1. for循環
            1. forloop.last
                {% if forloop.last %}
                    ...
            2. empty
                {% for i in x %}
                    ...
                {% empty %}
                    ...
                {% endfor %}
    4. 上傳文件
        form表單上傳文件
        # 文件的上傳
        def index(request):
            print(request.FILES)  # 上傳的文件列表對象
            for item in request.FILES:
                fileobj = request.FILES.get(item)  # 挨個獲取列表中每一個對象
                f = open('upload/%s' % fileobj.name, 'wb')
                item_file = fileobj.chunks()
                for line in item_file:
                    f.write(line)
                f.close()

            return HttpResponse("成功")

2. 學生管理系統
    - 老師 和 班級 是多對多的關係




6、Django模板系統(模板語言)(very important)
    - 基礎語法
        - 跟變量相關 {{ }}
            在Django的模板語言中按此語法使用:{{ 變量名 }}。

            當模版引擎遇到一個變量,它將計算這個變量,而後用結果替換掉它自己。 
            變量的命名包括任何字母數字以及下劃線 ("_")的組合。 變量名稱中不能有空格或標點符號。
            點(.)在模板語言中有特殊的含義。當模版系統遇到點("."),它將以這樣的順序查詢:

            ***** 屬性->方法->索引
            字典查詢(Dictionary lookup)
            屬性或方法查詢(Attribute or method lookup)
            數字索引查詢(Numeric index lookup)

            注意事項:

            若是計算結果的值是可調用的,它將被無參數的調用。 調用的結果將成爲模版的值。
            若是使用的變量不存在, 模版系統將插入 string_if_invalid 選項的值, 它被默認設置爲'' (空字符串) 。
            
            {# 取l中的第一個參數 #}
            {{ l.0 }}
            {# 取字典中key的值 #}
            {{ d.name }}
            {# 取對象的name屬性 #}
            {{ person_list.0.name }}
            {# .操做只能調用不帶參數的方法 #}
            {{ person_list.0.dream }}

            - Filter過濾器
                在Django的模板語言中,經過使用 過濾器 來改變變量的顯示。
                過濾器的語法: {{ value|filter_name:參數 }}

                使用管道符"|"來應用過濾器。

                例如:{{ name|lower }}會將name變量應用lower過濾器以後再顯示它的值。lower在這裏的做用是將文本全都變成小寫。

                注意事項:

                過濾器支持「鏈式」操做。即一個過濾器的輸出做爲另外一個過濾器的輸入。
                過濾器能夠接受參數,例如:{{ sss|truncatewords:30 }},這將顯示sss的前30個詞。
                過濾器參數包含空格的話,必須用引號包裹起來。好比使用逗號和空格去鏈接一個列表中的元素,如:{{ list|join:', ' }}
                '|'左右 沒有空格沒有空格沒有空格   ******
                 
                Django的模板語言中提供了大約六十個內置過濾器

                - 一些經常使用的過濾器
                    - default
                        若是一個變量是false或者爲空,使用給定的默認值。 不然,使用變量的值。

                        {{ value|default:"nothing"}}
                        若是value沒有傳值或者值爲空的話就顯示nothing
                        注:TEMPLATES的OPTIONS能夠增長一個選項:string_if_invalid:'找不到',能夠替代default的的做用。

                    - length
                        返回值的長度,做用於字符串和列表。

                        {{ value|length }}
                        返回value的長度,如 value=['a', 'b', 'c', 'd']的話,就顯示4.

                    - filesizeformat
                        將值格式化爲一個 「人類可讀的」 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如:

                        {{ value|filesizeformat }}
                        若是 value 是 1234567890,輸出將會是 1.1GB。

                    - slice
                        切片

                        {{value|slice:"2:-1"}}
                    - add
                        給變量加參數

                        {{ value|add:"2" }}
                        value是數字4,則輸出結果爲6。

                        {{ first|add:second }}
                        若是first是 [1,.2,3] ,second是 [4,5,6] ,那輸出結果是 [1,2,3,4,5,6] 。

                    - data
                        格式化

                        {{ value|date:"Y-m-d H:i:s"}}
                        可用的參數:
                            格式化字符    描述            示例輸出
                                a    'a.m.''p.m.'(請注意,這與PHP的輸出略有不一樣,由於這包括符合Associated Press風格的期間)    'a.m.'
                                A    'AM''PM''AM'
                                b    月,文字,3個字母,小寫。    'jan'
                                B    未實現。     
                                c    ISO 8601格式。 (注意:與其餘格式化程序不一樣,例如「Z」,「O」或「r」,若是值爲naive datetime,則「c」格式化程序不會添加時區偏移量(請參閱datetime.tzinfo) 。    2008-01-02T10:30:00.000123+02:00或2008-01-02T10:30:00.000123若是datetime是天真的
                                d    月的日子,帶前導零的2位數字。    '01''31'
                                D    一週中的文字,3個字母。    「星期五」
                                e    時區名稱 多是任何格式,或者可能返回一個空字符串,具體取決於datetime。    '''GMT''-500''US/Eastern'等
                                E    月份,特定地區的替表明示一般用於長日期表示。    'listopada'(對於波蘭語區域,而不是'Listopad')
                                f    時間,在12小時的小時和分鐘內,若是它們爲零,則分鐘停留。 專有擴展。    '1''1:30'
                                F    月,文,長。    '一月'
                                g    小時,12小時格式,無前導零。    '1''12'
                                G    小時,24小時格式,無前導零。    '0''23'
                                h    小時,12小時格式。    '01''12'
                                H    小時,24小時格式。    '00''23'
                                i    分鐘。    '00''59'
                                I    夏令時間,不管是否生效。    '1''0'
                                j    沒有前導零的月份的日子。    '1''31'
                                l    星期幾,文字長。    '星期五'
                                L    布爾值是不是一個閏年。    True或False
                                m    月,2位數字帶前導零。    '01''12'
                                M    月,文字,3個字母。    「揚」
                                n    月無前導零。    '1''12'
                                N    美聯社風格的月份縮寫。 專有擴展。    'Jan.''Feb.''March''May'
                                o    ISO-8601周編號,對應於使用閏年的ISO-8601週數(W)。 對於更常見的年份格式,請參見Y。    '1999年'
                                O    與格林威治時間的差別在幾小時內。    '+0200'
                                P    時間爲12小時,分鐘和'a.m。'/'p.m。',若是爲零,分鐘停留,特殊狀況下的字符串「午夜」和「中午」。 專有擴展。    '1 am''1:30 pm' / t3>,'midnight''noon''12:30 pm' / T10>
                                r    RFC 5322格式化日期。    'Thu, 21 Dec 2000 16:01:07 +0200'
                                s    秒,帶前導零的2位數字。    '00''59'
                                S    一個月的英文序數後綴,2個字符。    'st''nd''rd''th'
                                t    給定月份的天數。    28 to 31
                                T    本機的時區。    'EST''MDT'
                                u    微秒。    000000 to 999999
                                U    自Unix Epoch以來的二分之一(1970年1月1日00:00:00 UTC)。     
                                w    星期幾,數字無前導零。    '0'(星期日)至'6'(星期六)
                                W    ISO-8601週數,週數從星期一開始。    1,53
                                y    年份,2位數字。    '99'
                                Y    年,4位數。    '1999年'
                                z    一年中的日子    0到365
                                Z    時區偏移量,單位爲秒。 UTC以西時區的偏移量老是爲負數,對於UTC以東時,它們老是爲正。    -43200到43200


                    - safe
                        Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,緣由顯而易見,這樣是爲了安全。
                        可是有的時候咱們可能不但願這些HTML元素被轉義,好比咱們作一個內容管理系統,後臺添加的
                        文章中是通過修飾的,這些修飾多是經過一個相似於FCKeditor編輯加註了HTML修飾符的文本,
                        若是自動轉義的話顯示的就是保護HTML標籤的源文件。爲了在Django中關閉HTML的自動轉義有
                        兩種方式,若是是一個單獨的變量咱們能夠經過過濾器「|safe」的方式告訴Django這段代碼是安
                        全的沒必要轉義。

                        好比:

                        value = "<a href='#'>點我</a>"
                        {{ value|safe}}


                    - truncchars
                        若是字符串字符多於指定的字符數量,那麼會被截斷。截斷的字符串將以可翻譯的省略號序列(「...」)結尾。

                        參數:截斷的字符數

                        {{ value|truncatechars:9}}

                    - truncatewords
                        在必定數量的字後截斷字符串。

                        {{ value|truncatewords:9}}

                    - cut
                        移除value中全部的與給出的變量相同的字符串

                        {{ value|cut:' ' }}
                        若是value爲'i love you',那麼將輸出'iloveyou'.

                    - join
                        使用字符串鏈接列表,例如Python的str.join(list)

                    - timesince
                        將日期格式設爲自該日期起的時間(例如,「4天,6小時」)。

                        採用一個可選參數,它是一個包含用做比較點的日期的變量(不帶參數,比較點爲如今)。
                        例如,若是blog_date是表示2006年6月1日午夜的日期實例,而且comment_date是2006年6月1日08:00的日期實例,則如下將返回「8小時」:

                        {{ blog_date|timesince:comment_date }}
                        分鐘是所使用的最小單位,對於相對於比較點的將來的任何日期,將返回「0分鐘」。 

                    - timeuntil
                        似於timesince,除了它測量從如今開始直到給定日期或日期時間的時間。 
                        例如,若是今天是2006年6月1日,而conference_date是保留2006年6月29日的日期實例,則{{ conference_date | timeuntil }}將返回「4周」。

                        使用可選參數,它是一個包含用做比較點的日期(而不是如今)的變量。 若是from_date包含2006年6月22日,則如下內容將返回「1周」:

                        {{ conference_date|timeuntil:from_date }}


                - 自定義filter
                    - 自定義過濾器只是帶有一個或兩個參數的Python函數:

                        變量(輸入)的值 - -不必定是一個字符串
                        參數的值 - 這能夠有一個默認值,或徹底省略
                        例如,在過濾器{{var | foo:'bar'}}中,過濾器foo將傳遞變量var和參數「bar」。


                    - 建立 (步驟)
                        - 先在app目錄下建立一個templatetagspython包(名字必須這個)
                        - 在目錄中建立一個py文件
                        - 在py文件中按照固定的格式自定義一個filter(就是一個函數)
                        - 須要先導入 from django import template 
                            # 固定寫法,生成一個註冊實例對象
                            register = template.Library()

                            @register.filter()  # 告訴Django的模板語言我如今註冊一個自定義的filter
                            def add_str():pass  # 第一個參數是變量名, 第二個參數爲參數(最多一個)

                        - 使用:
                            - 重啓DJango項目
                            - 在HTML頁面中:{% load python文件名 %}
                            - {{ name|add_str:'好人啊' }}



                    - 例子:
                        - 自定義過濾器只是帶有一個或兩個參數的Python函數:

                            變量(輸入)的值 - -不必定是一個字符串
                            參數的值 - 這能夠有一個默認值,或徹底省略
                            例如,在過濾器{{var | foo:「bar」}}中,過濾器foo將傳遞變量var和參數「bar」。

                        - 自定義filter代碼文件擺放位置:

                            app01/
                                __init__.py
                                models.py
                                templatetags/  # 在app01下面新建一個package package
                                    __init__.py
                                    app01_filters.py  # 建一個存放自定義filter的py文件
                                views.py
                        
                        - 編寫自定義filter

                    
                            from django import template
                            register = template.Library()


                            @register.filter
                            def fill(value, arg):
                                return value.replace(" ", arg)


                            @register.filter(name="addSB")
                            def add_sb(value):
                                return "{} SB".format(value)
                        
                        - 使用自定義filter

                            {# 先導入咱們自定義filter那個文件 #}
                            {% load app01_filters %}

                            {# 使用咱們自定義的filter #}
                            {{ somevariable|fill:"__" }}
                            {{ d.name|addSB }}

                    - 注意:過濾器能夠連接
                        {{ text|escape|linebreaks }} 就是一個經常使用的過濾器鏈,它編碼文本內容,而後把行打破轉成<p> 標籤。


        - 跟邏輯相關 {% %}
            - 語法爲:{% tag %}

            - for
                <ul>
                {% for user in user_list %}
                    <li>{{ user.name }}</li>
                {% endfor %}
                </ul>

                for循環可用的一些參數:

                Variable            Description
                forloop.counter        當前循環的索引值(從1開始)
                forloop.counter0    當前循環的索引值(從0開始)
                forloop.revcounter    當前循環的倒序索引值(從1開始)
                forloop.revcounter0    當前循環的倒序索引值(從0開始)
                forloop.first        當前循環是否是第一次循環(布爾值)
                forloop.last        當前循環是否是最後一次循環(布爾值)
                forloop.parentloop    本層循環的外層循環(是個字典)

                forloop是一個字典

                - for ... empty
                    <ul>
                    {% for user in user_list %}
                        <li>{{ user.name }}</li>
                    {% empty %}
                        <li>空空如也</li>
                    {% endfor %}
                    </ul>
            
            - if,elif和else

                {% if user_list %}
                  用戶人數:{{ user_list|length }}
                {% elif black_list %}
                  黑名單數:{{ black_list|length }}
                {% else %}
                  沒有用戶
                {% endif %}
                
                固然也能夠只有if和else

                {% if user_list|length > 5 %}
                  七座豪華SUV
                {% else %}
                    黃包車
                {% endif %}
                
                注:
                    - if語句支持 andor、==、>、<、!=、<=、>=、innot inisis not判斷。


            - with    (就至關於起了一個別名)
                -     {% with p1.dream as dream %}
                        {{ dream }}   # dream 代替p1.dream
                    {% endwith %}
                - 定義一箇中間變量
                    {% with total=business.employees.count %}
                        {{ total }} employee{{ total|pluralize }}
                    {% endwith %}

            - csrf_token
                - 這個標籤用於跨站請求僞造保護。
                - 在頁面的form表單裏面寫上{% csrf_token %}
                    - 用這個後就能夠將中間件打開(這樣就安全了,知道是我可以收取的)
                    - 在表單中添加了一個隱藏的input標籤
                        - name csrfmiddlewaretoken
                        - value asksdasdas(64位)
            - # 註釋
                - {# ... #}

            - 母版(一個普通的html文件) block extends
                - 減小代碼的重複

                - 母版寫好
                    - 不一樣的地方用如下佔位
                    - {{ block contenter(name) }}

                        {{ endblock }}
                - 子文件
                    - {% extends '母版html' %}  # 繼承母版

                    - {% block contenter(name) %}  # 將母版中的站好位置額contenter填充
                            本身的html文件
                        {% endblock %}

                - 注意事項:
                    - {% extends '母版html' %}  # 繼承母版  必須寫在開頭
                    - {% extends name %}  name寫繼承的模板的名字字符串
                    - 自定義的內容寫在block中
                    - 定義多個block塊,通常要有js css


            - 注意事項
                - Django的模板語言不支持連續判斷,即不支持如下寫法:
                    {% if a > b > c %}
                    ...
                    {% endif %}
                - Dja的模板語言中屬性的優先級大於方法
                    def xx(request):
                        d = {"a": 1, "b": 2, "c": 3, "items": "100"}
                        return render(request, "xx.html", {"data": d})
                     如上咱們在使用render方法渲染一個頁面的時候,傳的字典d有一個key是items而且還有默認的 d.items() 
                     方法,此時在模板語言中:

                    {{ data.items }}
                    默認會取d的items key的值。


            - 組件 include
                - 能夠將經常使用的頁面內容如導航條,頁尾信息等組件保存在單獨的文件中,而後在須要使用的地方按以下語法導入便可。
                    {% include 'navbar.html' %}

            - 靜態文件相關(動態拿取STATIC_URL配置的名字)
                - 
                    {% load static %}
                    <img src="{% static "images/hi.jpg" %}" alt="Hi!" />
                    
                    引用JS文件時使用:
                    {% load static %}
                    <script src="{% static "mytest.js" %}"></script>
                    
                    某個文件多處被用到能夠存爲一個變量
                    {% load static %}
                    {% static "images/hi.jpg" as myphoto %}
                    <img src="{{ myphoto }}"></img>

                - get_static_prefix
                    {% load static %}
                    <img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />
                    
                    或者
                    {% load static %}
                    {% get_static_prefix as STATIC_PREFIX %}

                    <img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
                    <img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />

            - 自定義simpletag
                和自定義filter相似,只不過接收更靈活的參數。

                定義註冊simple tag
                @register.simple_tag

                @register.simple_tag(name="plus")
                def plus(a, b, c):
                    return "{} + {} + {}".format(a, b, c)

                使用自定義simple tag
                {% load app01_demo %}

                {# simple tag #}
                {% plus "1" "2" "abc" %}

            - inclusion_tag
                - 多用於返回html代碼片斷

                - 步驟
                    - 在app下建立templatetags的python包
                    - 在包下寫py文件 mytags
                    - 編輯文件
                        - from django import template
                        - register = template.Library()

                    - 定義函數
                        - 可接受參數
                        - 返回一個字典
                    - 函數加裝飾器
                        - @register.inclusion_tag('result.html')

                示例:

                    templatetags/my_inclusion.py

                    
                        from django import template

                        register = template.Library()


                        @register.inclusion_tag('result.html')
                        def show_results(n):
                            n = 1 if n < 1 else int(n)
                            data = ["第{}項".format(i) for i in range(1, n+1)]
                            return {"data": data}
                
                    templates/result.html

                        <ul>
                          {% for choice in data %}
                            <li>{{ choice }}</li>
                          {% endfor %}
                        </ul>
                    
                    templates/index.html
                        
                        <!DOCTYPE html>
                        <html lang="en">
                        <head>
                          <meta charset="UTF-8">
                          <meta http-equiv="x-ua-compatible" content="IE=edge">
                          <meta name="viewport" content="width=device-width, initial-scale=1">
                          <title>inclusion_tag test</title>
                        </head>
                        <body>

                        {% load my_inclusion %}

                        {% show_results 10 %}
                        </body>
                        </html>
 



- 細節
    input data屬性 value='是一個「-」連接的字符串'
相關文章
相關標籤/搜索