青魔法聖堂法術 Django的技術棧(持續更新)


title: 青魔法聖堂法術
tags: ,模板,小書匠,Python-高階法術
grammar_cjkRuby: true
---javascript

青魔法聖堂法術Django無論在哪種聖堂法術中都屬於佼佼者。

聖堂青魔法

**跳轉到文章結尾** 連接:https://www.cnblogs.com/Asterism-2012/p/10046765.html#headhtml

目錄

日誌管理前端

第三方登錄java

使用聖堂法術DRF進行接口開發python

Celery異步加載
mysql

電商中什麼是SPU 和SKU?git

富文本編輯器CKEditor程序員


web開發用戶綁定郵件,開發者郵箱的的申請流程web

開發環境

  • 操做系統:win10
  • Python版本:3.6.5
  • 集成開發工具:Pycharm
  • MySQL數據庫版本:5.7以上

推薦書單與學習網站:

  • Django官方文檔
  • Django Github源碼

Django-Web框架

django是一個web框架。(音標:[dʒæŋɡoʊ])ajax

Django用於快速開發數據驅動網站。他幾乎爲咱們封裝好了開發站點所須要作的一切冗餘操做。(避免重複造輪子,而且無需瞭解與服務器溝通的過程)
就像是咱們只須要製做玩具車的零件,Django框架爲咱們作好須要生產出一個玩具車的一切。
(在學習此課程以前,咱們要確保咱們電腦上已經安裝了所需的Python、Django、Mysql等環境,框架,數據庫而且配置好相關的環境變量)
Django的發佈時間是:2005年。

http報文的學習很重要

    ——學習Web開發很差好學習HTTP報文,將會「打拳不練功,到老一場空」,你花在犯迷糊上的時間比你沉下心來學習HTTP的時間確定會多不少。
(HTTP報文解釋:https://blog.csdn.net/zhll3377/article/details/7748086)


學習Django入門的兩個步驟:

  • [x] 掌握MVT框架的諸多應用方式。
  • [x] 如何使用Git源碼管理

什麼是Web框架?

Web框架爲應用程序提供了一套程序框架,這樣你能夠++專一++於編寫清晰、易維護的代碼,++而無需從頭作起。++ 簡單來講,這就是Django所能作的。
Django學習的三個參考:1.Django官網,2.Django源碼——Github,3.官方文檔(參考自傳智播客)
閱讀【django源碼】

MVC 與 MVT for Django

一. MVC(Model-View-Controller 三層功能模塊)

(1)核心思想:解耦
++下降++模塊之間的++耦合++,加強擴展性和移植性。而且向後版本兼容。
鬆散的三部分組合在一塊兒就是模型-視圖-控制器(MVC)的設計模式。簡單的說,++MVC++是一種++軟件開發的方法++,它把:

a. 代碼的定義和數據訪問的方法(模型)與

b. 請求邏輯 (控制器)還有

c. 用戶接口(視圖)這三部分分離開來。
 
(2)開發原則:高內聚,低耦合
高內聚的意思是,邏輯嚴謹,經過繼承體現。
MVC解析:1.Model:封裝對數據庫的訪問,內嵌ORM框架。

  1. View:封裝結果,內嵌模板引擎(.html)展現數據
  2. Controller:處理請求、業務邏輯、與M、V交互。它是MVC的核心

二. MVT(Model-View-Template 三層功能模塊)

核心思想:解耦
開發原則:高內聚,低耦合
MVC解析:

  1. Model:與MVC的M相同。
  2. View:與MVC的C相同。
  3. Template:與MVC的V相同。

三. [ORM框架]:

  • 對象-關係-映射 的簡稱
  • 內嵌於Model中.是別人寫來專門與數據庫交互的框架。被django開發者直接拿來使用,由於很好用。
    它的特色是:
    • 以面向對象的形式操做數據庫。
      經過模型類和對象的++映射關係++來完成CRUD(「增刪改查」)。
    • 把數據庫的行與相應的++映射對象++創建關聯,互相轉換,是自身無需直接操做庫。把查詢到的結果轉化爲對象、列表(我以爲是結果集)。

低耦合與高內聚:

內聚性:功能強度的度量,經過繼承體現(語名間,程序段間)模塊內部個元素彼此的緊密程度(邏輯性)。
耦合性(coupling):耦合高低取決於模板間接口的複雜性,調用的方式以及傳遞的信息。耦合性也叫塊間聯繫。指軟件系統結構中各模塊間相互聯繫緊密程度的一種度量模塊之間聯繫越緊密,其耦合性就越強,模塊之間越獨立則越差。耦合性就是模塊與模塊之間的親密關係,關係親密則依賴度高,若不然易於移植和拓展。

虛擬環境的使用:

爲何使用虛擬環境? 搭建獨立python運行環境。防止相同包的不一樣版本之間相互衝突和覆蓋.

  • 目錄:/home/.virtualenvs 能夠移動進去進行修改數據
  • 安裝虛擬環境的詳情請參照靈蛇法術篇。

Ajax:

MVT丟掉Template,依然能夠進行數據請求(交互),Ajax請求用json進行交互.這體現瞭解耦(先後端分離).

Django自帶的的輕量級服務器的啓動:

Django爲咱們準備了一個輕量級的Web開發服務器。僅用於開發階段使用。

(Py_Django2.0.6) E:\Git\demo_project>python manage.py runserver

Django開發步驟:

  • 安裝Django, 指定版本是2.0.6
pip install django==2.0.6
  • 查看Django版本(In shell):
import django 
django.get_version()
  • 建立項目(In shell):
(Py_Django2.0.6) E:\Git>django-admin startproject demo_project
  • 建立應用
(Py_Django2.0.6) E:\Git>cd demo_project 
(Py_Django2.0.6) E:\Git\demo_project>python manage.py startapp demoapp

Django項目文件解析:

先看一下表結構:
卷 Work & Learn 的文件夾 PATH 列表
卷序列號爲 0EA8-9214

E:.
│  manage.py
│  
├─demo_project
│  │  settings.py
│  │  urls.py
│  │  wsgi.py
│  │  __init__.py
│  │  
│  └─__pycache__
│          settings.cpython-35.pyc
│          __init__.cpython-35.pyc
│          
└─demo_app
    │  admin.py
    │  apps.py
    │  models.py
    │  tests.py
    │  views.py
    │  __init__.py
    │  
    └─migrations
            __init__.py

項目文件目錄說明:

  • manage.py: 一個++命令行工具++,與項目進行交互
  • demo_project:項目的同名文件,這個是隨着項目的名稱改變二改變的: 項目配置文件的存放位置,真正意義上的python包。

項目的同名文件(HELLO)下:(項目真正的python包)

  • __init__.py : 一個空文件,告訴python該目錄是一個Python包。
  • settings.py: 該Django項目的++設置和配置++
  • urls.py: 該項目的url聲明,一份由django驅動的"++網頁目錄++"
  • wsgi.py 一個WSGI++兼容的服務器入口++,以便運行你的項目
    應用於項目同名文件間無關係,無依賴。須要安裝應用來使用。

應用下的文件:

  • urls.py: 用於定義子路由, 可是這個文件不是django自帶的,須要手動建立。一般用正則表達式來表示url,本質是視圖與模板之間的映射關係表。
import django.conf.urls import url  # 導入url
from .views import DemoView
urlpatterns = [
    url(r'^index/$', DemoView);
]
  • models.py: 模型層的主要內容

用於定義模型類,定義表結構,以便用於存放數據。

這些內容其實能夠好好研究一下,可是這不是目前主要的學習內容,能夠稍後進行學習。

settings.py 文件配置介紹

  • 監聽IP地址 就是說容許這個地址來訪問咱們的web服務器,若是填寫」*「號則表示容許全部網段的設備進行訪問。
ALLOWED_HOSTS = ["*"]       # 本來這裏是一個空列表,可是如今就表明開放了訪問,也能夠進行指定IP如 10.30.36.111的設備。
  • 根路徑指定:
BASE_DIR (根路徑指定)
  • 主路由指定:
ROOT_CONF (主路由指定)
  • 安裝應用:

django自身自帶着不少應用,存放在INSTALL_APPS列表中,咱們能夠把開發所須要須要的第三方應用以及咱們建立的應用追加到列表中。

INSTALL_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 這個是個人應用,這裏是標準寫法,也能夠簡化爲‘demo_app’
    'demo_app.apps.DemoAppConfig',
]

ENGINE(引擎)
在項目setting.py中添加應用的作法能夠叫作安裝應用, 也能夠叫作註冊應用。

  • 在settings.py中安裝數據庫
DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'test2',
            'USER': '用戶名',
            'PASSWORD': '密碼',
            'HOST': '數據庫服務器ip,本地可使用localhost',
            'PORT': '端口,默認爲3306',
        }
    }
  • 其實django.db.backends.mysql 意思就是 指向django/db/backends/mysql這個目錄內寫好的代碼:他們都是Django開發者寫好支持面向對象操做數據庫的,默認狀態下只支持四個寫好的,若是須要額外的數據庫來工做,那麼能夠本身寫,本身寫,本身寫,對。

  • 項目配置目錄下的__init__.py文件設置,要寫上這一行代碼,表示在django上安裝了Mysql客戶端:
import pymysql
pymysql.install_as_MySQLdb()

SQLite3 數據庫

SQLite3 是一個django自身支持的數據庫

開發流程綱要:

  1. 若是存在的話:首先建立好放置templates模板文件和static靜態文件的文件夾
  2. 配置setting:安裝應用、設置模板路徑、設置靜態文件路徑
  3. 配置主路由,而且在應用中配置好子路由
  4. 配置數據模型類
  5. 配置Views視圖中的業務邏輯
    (這是一個典型的後臺思惟的作法,這是一個很好的流程,但事實上,這並不要求你必定要按照這個流程去開發站點,卻頗有利於新手的掌握。)

MVT中的M:模型——Models.py

  • 首先要注意的事是每一個數據模型都是 django.db.models.Model 的子類。它的父類 Model 包含了全部必要的和數據庫交互的方法,並提供了一個簡潔漂亮的定義數據庫字段的語法。 信不信由你,這些就是咱們須要編寫的經過Django存取基本數據的全部代碼。
    每一個模型至關於單個數據庫表,每一個屬性也是這個表中的一個字段。 屬性名就是字段名,它的類型(例如 CharField )至關於數據庫的字段類型 (例如 varchar )

定義模型

說明:

  • 排序會增長數據庫的開銷:在磁盤的物理佔用會變大
  • django根據屬性的類型肯定如下信息:
    • 當前選擇的數據庫支持字段的類型
    • 渲染管理表單時使用的默認html控件
    • 在管理站點最低限度的驗證
  • Django根據屬性的類型肯定如下信息:
    • 字段類型與約束條件
    • 渲染管理表單時使用的默認html控件
  • Django會默認生成主鍵字段(id)。咱們也能夠本身定義,這樣他就不會本身再生成。
  • 字段名不能包含兩個連續下劃線:如a__b;(會影響查詢的標識符)
  • isDelete 寫在前面:它不是一個字段類型,進行數據保護的一個布爾類型字段,稱爲邏輯刪除。

代碼:

CharField是字段類型,max_length是約束條件(能夠叫作字段屬性)。
BooleanField是字段類型,default是字段屬性。

定義字段

上面的代碼已經進行示例過了,這是一個詳細說明。

  • 導入from django.db import models
  • 經過models建立字段類型的對象,而且賦予一個屬性名
  • 對於重要的數據,都作邏輯刪除,不作物理刪除,實現方法是定義isDelete屬性,類型爲BooleanField,默認值爲False。
  • DateField(若是不寫參數,則能夠(須要)本身維護)
  • 沒有特別須要,咱們不使用上傳文件、上傳圖片字段。而是咱們直接上傳文件到服務器磁盤的目錄中,將其路徑存下來(看成字符串)使用。圖片等媒體文件在數據庫中的保存方式是二進制方式保存,它們體積太大,會佔用太多的資源。
  • default默認值約束,更像是django的邏輯約束,而不是物理約束。它不該用於數據庫,只決定於對象字段如何建立。

進行數據遷移

生成遷移就是生成模型類與數據庫之間的映射表,使django的開發者可以使用models中的增刪改查的方法來直接操做數據庫,而無需懂得SQL語句。(除非你是一個業餘愛好者,不然其實仍是要懂的,程序員不懂不行啊)。

  • 首先要將APP 添加到settings.py配置文件的INSTALL_APPS中去。
    不然在生成數據遷移的時候django會找不到你的應用。
    則會顯示:No changes detected 沒有變化檢測
No changes detected
  • 這裏使用的是文檔型數據庫SQLite3,這樣就無需配置。固然也可使用MySQL數據庫或者其餘數據庫。反正我不是嫌麻煩嘛。mysql數據庫的配置能夠在「settings.py 文件配置介紹」中查閱。

  • 首先進行生成遷移文件,統稱生成遷移。

(Py_Django2.0.6) E:\Git\demo_project>python manage.py makemigrations

成功則顯示是這樣的。

這個時候就能夠看到遷移文件已經生成了。能夠來這個文件裏面看它的源碼,這就是這個。可是這一步只是生成了一個遷移文件,而沒有在數據庫中創表。

  • 因此要進行執行遷移文件,就叫執行遷移。
(Py_Django2.0.6) E:\Git\demo_project>python manage.py migrate

成功以後的顯示:

查看一下數據庫,表已經創建好了:

字段類型

說明表:

  • AutoField:一個根據實際ID自動增加的IntegerField,一般不指定
    若是不指定,一個主鍵字段將自動添加到模型中
  • BooleanField:true/false(布爾映射mysql是tinyint類型的) 字段,此字段的默認表單控制是CheckboxInput
  • NullBooleanField:支持null、true、false三種值
  • CharField(max_length=字符長度):字符串,默認的表單樣式是 TextInput
  • TextField:大文本字段,通常超過4000使用,默認的表單控件是Textarea
  • IntegerField:整數
  • DecimalField(max_digits=None, decimal_places=None):使用python的Decimal實例表示的十進制浮點數
    • DecimalField.max_digits:位數總數
    • DecimalField.decimal_places:小數點後的數字位數
  • FloatField:用Python的float實例來表示的浮點數
  • DateField[auto_now=False, auto_now_add=False]):使用Python的datetime.date實例表示的日期
    • 參數DateField.auto_now:每次保存對象時,自動設置該字段爲當前時間,用於"最後一次修改"的時間戳,它老是使用當前日期,默認爲false
    • 參數DateField.auto_now_add:當對象第一次被建立時自動設置當前時間,用於建立的時間戳,它老是使用當前日期,默認爲false
    • 該字段默認對應的表單控件是一個TextInput. 在管理員站點添加了一個JavaScript寫的日曆控件,和一個「Today"的快捷按鈕,包含了一個額外的invalid_date錯誤消息鍵
    • auto_now_add, auto_now, and default 這些設置是相互排斥的,他們之間的任何組合將會發生錯誤的結果
  • TimeField:使用Python的datetime.time實例表示的時間,參數同DateField
  • DateTimeField:使用Python的datetime.datetime實例表示的日期和時間,參數同DateField
  • FileField:一個上傳文件的字段
  • ImageField:繼承了FileField的全部屬性和方法,但對上傳的對象進行校驗,確保它是個有效的image

字段屬性(選項)

  • 經過字段選項,能夠實現對字段的約束
  • 在字段對象時經過關鍵字參數指定
  • null:若是爲True,Django 將空值以NULL 存儲到數據庫中,默認值是 False
  • blank:若是爲True,則該字段容許爲空白,默認值是 False
  • 對比:null是數據庫範疇的概念,blank是表單驗證證範疇的
  • db_column:控制字段名稱用的,本身手動指定一個字符串做爲字段的名稱。
  • db_index:若值爲 True, 則在表中會爲此字段建立索引,加速查詢
  • default:默認值,不會改變於數據庫字段的屬性,上面已經說過了,不是物理層面的約束。
  • primary_key:若爲 True, 則該字段會成爲模型的主鍵字段
  • unique:若是爲 True, 這個字段在表中必須有惟一值
  • verbose_name:定義字段名。與db_column不一樣,它是面向用戶的。

元選項(元類)

  • 在模型類中定義類Meta,用於設置元信息,獲取查詢數據的時候,默認(由小到大)給數據的顯示方式。
class Meta:
  • 元信息db_table:定義數據表名稱用的,指定一個字符串做爲表的名稱,若是不使用,系統也會自動生成表的名稱。
class Meta:
    db_table='新的數據表名稱'
  • ordering排序:對象的默認排序字段,獲取對象的列表時使用,接收屬性構成的列表。排序會增長數據庫的開銷:在磁盤的物理佔用會變大
class BookInfo(models.Model):
    ...
    class Meta():
        ordering = ['id']       # 字符串前加-表示倒序,不加-表示正序

class BookInfo(models.Model):
    ...
    class Meta():
        ordering = ['-id']      # 表示倒序排序

自定義管理器:

  • objects是默認的manager類型的對象,用於與數據庫進行交互
  • 從哪裏來的?繼承來的。
  • manager是django定義好的類,它是ORM的核心。
  • 當定義模型類時,沒有指定管理器,則django會爲模型類提供一個名爲objects的管理器。
  • 支持自定義管理器。(支持明確指定模型類的管理器)
class BookInfo(models.Model):
    ...
    books = models.Manager()
    #注意,當咱們這樣作的時候。默認的object就沒了
    books1 = models.Mnager()
    #這樣作咱們就要能夠擁有多個管理器
    #可是以上代碼這樣寫是沒有意義的

管理器對象Manager

  • 管理器是Django的模型進行數據庫查詢操做的接口(ORM),Django應用的每個模型都擁有至少一個管理器。
  • 自定義管理器主要應用於兩種狀況:
    • 改變默認查詢集的結果,改變建立方法

    • 設置模型類的建立

'''咱們要經過本身定義的管理器的類繼承Manager,經過重寫++get_queryset++方法來完成更改默認查詢集'''
class BookInfoManager(models.Manager):
    def get_queryset(self):
        return super(BookInfoManager,self).get_queryset().filter(isDelete=False)
  • 注意當爲模型類指定管理器以後 ,默認的管理器就不會再生成(django不會爲模型類生成名爲objects的默認管理器)。
  • 更深層次的理解:model層只是映射,若是數據庫中已存在(而且一一對應),那麼就不用遷移,能夠直接使用。沒錯:就是這樣,直接使用

經過模型類修改數據內容

hero = HeroInfo()
hero.hero_name = '俄狄浦斯'
hero.save()

經過模型類查看數據內容

外鍵:表之間的關係

這一個概念是基礎概念,很容易理解,可是要須要多多實際練習。

  • 關係的類型包括
    • ForeignKey:一對多,將字段定義在多的一段端中(就是在子級表中定義一個字段指向父級表),就是外鍵。例如一本書中有多個英雄,在英雄表中定義「書籍字段」,指向該英雄所對應的書籍。
    • ManyToManyField:多對多,將字段定義在兩端中 。例如朋友與朋友之間,就是多對多,你能夠是他們的朋友,他們也有本身的朋友。
    • OneToOneField:一對一,將字段定義在任意一端中。好比身份證,一我的只能有一張身份證。
  • 能夠維護遞歸的關聯關係,使用'self'指定,詳見「自關聯」
  • 跨表的字段存儲的原理就是至關於一個指針,存儲對方的主鍵。相似於蟲洞穿越。

三種關係之間訪問方式:

  • 用一訪問多:對象.模型類小寫_set
bookinfo.heroinfo_set
  • 用一訪問一:對象.模型類小寫
heroinfo.bookinfo
  • 訪問id:對象.屬性_id
heroinfo.book_id

MVT中的V:視圖——Views.py

所謂的視圖函數(或 視圖 ),只不過是一個接受 Web 請求並返回 Web 響應的 Python 函數。實際上,該響應能夠是++一份網頁的 HTML 內容、一次重定向、一條 404 錯誤、一份 XML 、文檔、一幅圖片,或其它任何東西++。視圖自己包含返回該響應所需的任意邏輯
視圖的本質就是函數。

  • 能夠將views命名爲其餘,但一般並不是必要。除非你是獨立開發一個用途不明的站點。
  • 第一個參數是HttpRequest;當Django接收一個請求報文後會構造一個reqest對象,可是response須要咱們本身構建
  • 必須返回HttpResponse對象,或它(HttpResponse)的子類。

URLconf(url配置)

  • 根級url配置:settings中>ROOT_URLCONF(自動生成)
  • 子、主路由(手動配置)
  • 能夠將urls.py命名爲其餘,但一般並不是必要
  • 在url的正則中,用小括號括起來的部分將做爲參數傳遞給視圖函數(字符串類型)。
  • 每一個正則表達式前面的r表示字符串不轉義
  • 請求的url被看作是一個普通的python字符串,進行匹配時不包括get或post請求的參數及域名
http://www.itcast.cn/python/1/?i=1&p=new,只匹配「/python/1/」部分
  • 正則表達式非命名組,經過位置參數傳遞給視圖
url(r'^([0-9]+)/$', views.detail, name='detail'),
  • 正則表達式命名組,經過關鍵字參數(P符傳參)傳遞給視圖,本例中關鍵字參數爲id
url(r'^(?P<id>[0-9]+)/$', views.detail, name='detail'),

命名空間(給URL起名字)

(用於反向解析)

  • 在視圖函數重定向會使用到
  • 模板中連接會使用到
主路由
    url(r'^', include('booktest.urls', namespace='booktest')),
    子路由
    url(r'^([0-9]+)/$', views.detail, name='detail'),

錯誤視圖

(當關閉調試模式,DEBUG=False時候纔會啓用,同時要開放訪問)

  • 自定義一個404.html的模板便可(在找不到頁面時候系統會自動顯示這個頁面。)
    默認的404視圖將傳遞一個request_path參數給模板:request_path,它是致使錯誤的URL
...
    找不到{{request_path}}這個路徑
        </body>
    </html>
  • 自定義500.html模板(視圖代碼運行錯誤時候會顯示)
    不會傳遞參數給模板
  • 自定義400.html模板(錯誤請求:當用戶進行的操做在安全方面可疑的時候,例如篡改會話cookie)

HttpRequest對象:

封裝了全部請求報文。

屬性

  • 下面除非特別說明,屬性都是隻讀的
  • path:一個字符串,表示請求的頁面的完整路徑,不包含域名
  • method:一個字符串,表示請求使用的HTTP方法,經常使用值包括:'GET'、'POST'
  • encoding:一個字符串,表示提交的數據的編碼方式
    • 若是爲None則表示使用瀏覽器的默認設置,通常爲utf-8
    • 這個屬性是可寫的,能夠經過修改它來修改訪問表單數據使用的編碼,接下來對屬性的任何訪問將使用新的encoding值
  • GET:一個相似於字典的對象,包含get請求方式的全部參數
  • POST:一個相似於字典的對象,包含post請求方式的全部參數
  • FILES:一個相似於字典的對象,包含全部的上傳文件
  • COOKIES:一個標準的Python字典,包含全部的cookie,鍵和值都爲字符串
  • session:一個既可讀又可寫的相似於字典的對象,表示當前的會話,只有當Django 啓用會話的支持時纔可用,詳細內容見「狀態保持」

方法

  • is_ajax():若是請求是經過XMLHttpRequest發起的,則返回True

QueryDict對象

QueryDict對象是一個類字典的對象,它的特色是:它也是以鍵值對的形式保存數據,可是它的每個鍵均可以包括一個或多個值。也能夠這麼說:它的鍵是能夠重複的

  • GET屬性和POST屬性都是QueryDict對象
  • 方法get():根據鍵獲取值
    • 只能獲取鍵的一個值
    • 若是一個鍵同時擁有多個值,獲取最後一個值
request.GET.get('鍵',default)
    request.POST.get('鍵',default)
    或簡寫爲
    request.get['鍵']
    request.get['鍵]
  • 方法getlist():根據鍵獲取(多個)值
    • 將鍵的值以列表返回,能夠獲取一個鍵的多個值
request.get.getlist('鍵',default)
    request.POST.getlist('鍵',default)

在本網站中不用特地指定域名。

  • 如何本頁面是表單的提交頁面,那麼直接獲取值就行了。(reques.POST)

HttpResopnse對象

是咱們須要返回的一個對象。

  • 調用模板(用於返回對象)的完整過程
from django.http import HttpResponse
from django.template import RequestContext, loader
 
def index(request):
    t1 = loader.get_template('polls/index.html')
    context = RequestContext(request, {'h1': 'hello'})
    return HttpResponse(t1.render(context))
#加載的過程,就是將頁面上的模板讀過來
#而後渲染的過程,是將頁面上的模板替換的過程
  • render是它的簡寫

    屬性

  • content:表示返回的內容,字符串類型(返回的部分:所處於body)
  • charset:表示response採用的編碼字符集,字符串類型
  • status_code:響應的HTTP響應狀態碼
  • content-type:指定輸出的MIME類型(多媒體文件後綴名類型如.html.py等:表示爲"text/html")

    方法

  • init :使用頁內容實例化HttpResponse對象
  • write(content):以文件的方式寫

response.write(任何格式的數據類型)
  • flush():以文件的方式輸出緩存區
  • set_cookie(key, value='', max_age=None, expires=None):設置Cookie
    • cookie就是存儲在瀏覽器上的一段文本信息(是response爲咱們返回回來的一個鍵值對),(以後會會自動加到請求報文頭中提交請求),跨域名是不能共享cookie信息的。 但在整個域名內,cookie均可用。並且一旦寫進去,會一直保存(至多兩個星期)。
    • key、value都是字符串類型
    • max_age是一個整數,表示在指定秒數後過時
    • expires是一個datetime或timedelta對象,會話將在這個指定的日期/時間過時,注意datetime和timedelta值只有在使用PickleSerializer時纔可序列化
    • max_age與expires二選一
    • 若是不指定過時時間,則兩個星期後過時

寫一個cookie返回給瀏覽器:

response = HttpResponse()
response.set_cookie('鍵','值')
#在這以後,它會保存至多兩週,而且在當前域名下會自動加入到請求頭部(request headers)中

在服務器端接收cookie:

#獲取cookie對象
cookie = request.COOKIE
if cookie.has_key

COOKIE對象的方法

cookie對象是區別於網站的,應用於當前域名內全部頁面。
出於安全考慮,是瀏覽器提供的限定,它隔離不一樣的網站。
例子:京東與淘寶的推薦。沒法相互讀取cookie信息。

  • 獲取cookie對象
cookie = request.COOKIE
  • 獲取cookie的值
#cookie對象
cookie['鍵']
#或者
cookie
  • 判斷cookie是否擁有某個鍵
#這是python2中的寫法
cookie.has_key('鍵')
#Python3是這樣寫的
if '鍵' in cookie
  • 刪除Cookie
response = HttpResponse('ok')
response.delete_cookie('hello')
return response

HttpResponseRedirect重定向(繼承於Response)

告訴瀏覽器從新發送請求

  • 平時仍是用簡寫redirect重定向(簡寫)

預留部分:子類JsonResponse(繼承於Response)

  • 返回json數據,通常用於異步請求
  • init (data)
  • 幫助用戶建立JSON編碼的響應
  • 參數data是字典對象
  • JsonResponse的默認Content-Type爲application/json

    from django.http import JsonResponse

    def index2(requeset):
    return JsonResponse({'list': 'abc'})

    狀態保持

  • Http是無狀態的:它不會(直接)記錄你以前與這個網站交互的信息。
  • 會話:客戶端與服務器端的一次通訊,就叫作會話。
  • cookie與session均可以實現狀態保持:記錄交互(會話相關數據)的信息。
  • cookie將會話信息存儲到客戶端,而session將會話信息存儲在服務器端。推薦使用session來存儲敏感信息。
  • 狀態保持的目的是爲了在一段時間內跟蹤請求者的狀態,實現跨頁訪問當前請求者的數據。
  • 不一樣請求者之間相互隔離:他們不會共享session數據
  • session的值默認存在數據庫裏

    啓用session

  • 在setting中註冊session應用(通常是默認添加的),而且添加中間件:

    INSTALL_APP=[
    ...
    'django.contrib.session',
    ]

    MIDDLEWARE_CLASSES=[
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    ]
    session對象賦值(假字典)

    request.session['鍵']='值'
  • 禁用會話:刪除上面指定的兩個值,禁用會話將節省一些性能消耗

    使用session

  • 啓用會話後,每一個HttpRequest對象將具備一個session屬性,它是一個類字典對象
  • get(key, default=None):根據鍵獲取會話的值
  • clear():清除全部會話
  • flush():刪除當前的會話數據並刪除會話的Cookie
  • del request.session['member_id']:刪除會話
  • 讓我困惑的是,爲何使用了del刪除會話信息,session表中仍存在一個字段
  • session依賴於cookie;每一個cookie中都儲存着一個sessionid,用於和服務器中的session信息進行匹配。

會話過時時間

  • set_expiry(value):設置會話的超時時間
  • 若是沒有指定,則兩個星期後過時
  • 若是value是一個整數,會話將在values秒沒有活動後過時
  • 若果value是一個imedelta對象,會話將在當前時間加上這個指定的日期/時間過時
  • 若是value爲0,那麼用戶會話的Cookie將在用戶的瀏覽器關閉時過時
  • 若是value爲None,那麼會話永不過時
    • 修改視圖中login_handle函數,查看效果
def login_handle(request):
    request.session['uname'] = request.POST['uname']
    # request.session.set_expiry(10)
    # request.session.set_expiry(timedelta(days=5))
    # request.session.set_expiry(0)
    # request.session.set_expiry(None)
    return redirect(reverse('main:index'))

session存到了哪裏去?如何更改?

  • 存到了數據庫中,咱們能夠更改;可是要更改session的引擎。它還能夠存到不一樣的地方去。
  • 使用存儲會話的方式,可使用settings.py的SESSION_ENGINE項指定
    基於數據庫的會話:這是django默認的會話存儲方式,須要添加django.contrib.sessions到的INSTALLED_APPS設置中,運行manage.py migrate在數據庫中安裝會話表,可顯示指定爲
SESSION_ENGINE='django.contrib.sessions.backends.db'

基於緩存的會話:只存在本地內在中,若是丟失則不能找回,比數據庫的方式讀寫更快

SESSION_ENGINE='django.contrib.sessions.backends.cache'

能夠將緩存和數據庫同時使用:優先從本地緩存中獲取,若是沒有則從數據庫中獲取

SESSION_ENGINE='django.contrib.sessions.backends.cached_db'

使用Redis緩存session

會話還支持文件、純cookie、Memcached、Redis等方式存儲,下面演示使用redis存儲
安裝包

pip install django-redis-sessions

修改settings中的配置,增長以下項

SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 0
SESSION_REDIS_PASSWORD = ''
SESSION_REDIS_PREFIX = 'session'

詳解url函數

Django url()能夠接收四個參數,分別是兩個必選參數:regex、view 和++兩個可選參數++:kwargs、name,接下來詳細介紹這四個參數。

  1. regex: 正則表達式,與之匹配的 URL 會執行對應的第二個參數 view。
  2. view: 用於執行與正則表達式匹配的 URL 請求。
  3. kwargs: 視圖使用的字典類型的參數。
  4. name: 用來反向解析 URL。
      值得一提的是:使用 django.http.HttpResponse() 來輸出 "Hello World!"。(他能夠解析html語言)該方式將數據與視圖混合在一塊兒,並不符合 Django 的 MVC 思想。

路由 (網絡工程術語)

路由(routing)是指分組從源到目的地時,決定端到端路徑的網絡範圍的進程 [1]。
路由是指路由器從一個接口上收到數據包,根據數據包的目的地址進行定向並轉發到另外一個接口的過程。
路由工做包含兩個基本的動做:
一、肯定最佳路徑
二、經過網絡傳輸信息

manage.py 項目管理器的相關操做

python manage.py runserver 0.0.0.0:8008(後面的聲明端口是可變動的,默認爲8000)

#將應用中的modles.py中的數據表信息遷移到本地數據庫(在數據庫建表)。  
python manage.py makemigrations 生成遷移  
 
python manage.py migrate 執行遷移  
 
python manage.py flush 刪除遷移  
 
python manage.py shell 運行Shell:  
 
python manage.py createsuperuser 建立超級用戶

Django的 QuerySet 的屬性

QuerySet 能夠被構造,過濾,切片,作爲參數傳遞,這些行爲都不會對數據庫進行操做。只要你查詢的時候才真正的操做數據庫。(更多相關: https://blog.csdn.net/com_ma/article/details/79113291)

manage.py 和 django-admin.py 的區別

manage.py 生成應用多了[auth]、[contenttypes]、[sessions]、[staticfiles]
(詳情請參閱:https://blog.csdn.net/ldw220817/article/details/78575409)

視圖配置與URL,部分參考於Djangobook2.0

動態內容(顯示時間の源代碼)

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)

動態URL

from django.http import HttpResponse
import datetime
def hello(request):
    return HttpResponse("Hello world")
def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

Templates 模板

(部分參考於Djangobook2.0)

模板就是定義一些咱們顯示的內容,一個模板能夠被多個視圖(Views)使用。

  • 包括兩個內容:
    • 靜態html頁面
    • 動態插入內容部分(經過模板語言生成)
  • 設置模板路徑,在settings.py中:

    TEMPLATES = [
    DIR:[os.path.join(BASE_DIR,'templates)]
    ]
    #模板引擎會按照順序搜索DIR和APP_DIR兩個列表中的路徑,以查找模板文件。
  • 在應用中也能夠有templates目錄。在何時使用它?除非這個應用有很高的移植性,而且打算移植。
  • Django模板語言-DTL(我猜是Django-Templates-Language):定義在django.templates包中
    Django處理模板分爲兩個階段:加載:讀取文件的內容到內存,渲染:填坑?。
    我很好奇課件末尾去除模板硬編碼的內容是什麼。
  1. 加載:根據給定的表示找到模板而後預處理,一般會將它編譯好放在內存中(找模板)。
loader.get_template(template_name),返回一個Template對象
  1. 渲染:使用Context數據對模板插值並返回生成的字符串(渲染模板)。
    瀏覽器沒法之間解析DTL模板語言,須要咱們在發給瀏覽器以前解析掉它。
Template對象的render(RequestContext)方法,使用context渲染模板
  1. 完整源碼:
from django.template import loader, RequestContext
from django.http import HttpResponse
 
def index(request):
temp = loader.get_template('temtest/index.html')
context = RequestContext(request, {})
return HttpResponse(tem.render(context))

因而就有了快捷函數

  1. render_to_string('字符串')——它等同於Httpresponse。
  2. render()是渲染的意思,他會解析模板
    render -渲染-是處理視圖邏輯路徑的,
    換句話說,他直接從給templates中尋找文件
render(request,'模板',context)

關於render()的"全稱":

from django.http import HttpResponse
from django.template import ReqestContext,loader
temp = loader.get_template('booktest/index.html')
return HttpResponse(temp.render())
#-----------以上-------------

它很長,因此有了render(),他接受三個參數,分別是request,模板路徑,上下文管理器(字典類型,通常爲context,也能夠寫做local()"全局選擇",一般能夠直接定義一個字典:如{'info':'Hi'})

  • redriect -重定向-是處理資源定位符路徑的(url路徑)
    簡單來講,他直接執行在url中寫入路徑的動做,以配合新的業務邏輯層的視圖函數,但卻不能在templates文件夾中尋找諸如以html等後綴結尾的視圖邏輯曾的,頁面文件

模板語言DTL

包含:

  1. 變量
  2. 標籤{% 代碼段 %}
  3. 過濾器
  4. 註釋{# DTL內容或者html#}(只有這種方法才能註釋掉代碼,不然會報錯)
  • 模板繼承:爲了更好的可讀性,應該在{% block 名稱 %}{% endblock 名稱%}中填上名稱。

    變量:

  • 語法:
{{ variable}}   <!--這裏寫變量名--!>
  • 當模板引擎遇到一個變量,就將計算這個變量的值,而後將jie'guo'shu'chu
  • 變量名只能由字母數字下劃線組成(不能如下劃線開頭),和點組成
  • 當遇到'.'時,模板的會按照下列順序查詢:
  1. 字典查詢foor['bar']
  2. 屬性或方法查詢foo.bar
  3. 數字索引查詢,foo[bar]
  • 變量不存在,模板系統將插入''(空字符串)。
  • 模板中調用方法時候,系統會自動加括號();同時不能傳遞參數。
  • 更深層次的理解:model層只是映射,若是數據庫中已存在(而且一一對應),那麼就不用遷移,能夠直接使用。沒錯:就是這樣,直接使用。
  • 因此結合遇到'.'時候的查詢順序,我能夠打印表名:只須要在模型類中定義方法就行了。只能用get獲取單個數據時候使用。
class BookInfo(models.Model):
...
def tableName():
    return verbpse_name
'''
view:   book=BookInfo.objects.all()
templates:   {{book.tableName}}
'''
  • for標籤
{% for ... in ...%}
{% forloop.countrt %}       {# 獲取循環索引值 #}
{% forloop.countrt0 %}       {# 從0開始獲取循環索引值 #}
{% empty %}     {# 若爲空 #}
 
{% endfor %}
  • if標籤
{% if... %}
{% elif %}
{% else %}
{% endif %}
  • 多行註釋comment
{% comment %}
{% endcomment %}
  • 反向解析url
{% url 'name' p1 p2 %}
{% comment %}這裏的p1,p2是兩個參數{% endcomment %}
  • 跨站請求僞造攻擊防禦csrf_token
{% csrf_token %}{# 通常寫在form表單中,保護表單中的數據 #}
  • 布爾標籤:and、or,and比or的優先級高
  • block、extends:詳見「模板繼承」
  • autoescape:詳見「HTML轉義」

反向解析

正向解析是給了一個地址咱們經過正則去匹配URL的規則,而反向解析,是咱們經過RUL去請求得到一個,生成一個地址.

過濾器

  • 語法
    {{ 變量|過濾器 }}
    {{ name|lower }}{{# 將變量name進行小寫運算,而後輸出 #}}

  • 判斷是否可以整除
{{ 變量|divisibleby:'整數'}}

模板繼承

模板繼承就是找共同點,牢記繼承的三層結構。讓他影響你的思想,三層結構融爲一體。
並且你必定要記住,能夠跨層填坑(重寫)。並且,子模版就是填坑,先填哪個無所謂,只要填上就行。

  • 有關學習克隆魔法的哲思:每個學生在學習高階克隆魔法以前,都應該學習三層繼承結構,而且完成一個本身的頁面做爲做業交給本身的老師。
base:
    base_user:
        user_Center,user_Address
    base_good:
        good_list,good_show

模板是一個文本,用於分離文檔的表現形式和內容。模板一般用於產生HTML,可是Django的模板也能產生任何基於文本格式的文檔。這些功能很是COOL。
 
用兩個大括號括起來的文字(例如 {{ person_name }} )稱爲 變量(variable) 。
 
被大括號和百分號包圍的文本(例如 {% if ordered_warranty %} )是 模板標籤(template tag) 。標籤(tag)定義比較明確,即: 僅通知模板系統完成某些工做的標籤。
 
有一個關於filter過濾器的例子,它是一種最便捷的轉換變量輸出格式的方式。如這個例子中的{{ship_date|date:」F j, Y」 }}
在Python代碼中使用Django模板的最基本方式以下:
能夠用原始的模板代碼字符串建立一個 Template 對象, Django一樣支持用指定模板文件路徑的方式來建立 Template 對象;
調用模板對象的render方法,而且傳入一套變量context。它將返回一個基於模板的展示字符串,模板中的變量和標籤會被context值替換。

在模板文件中書寫模板語言

>><h1>{{ HELLO }} </h1>

向Django說明模板文件的路徑;全局配置文件: Setting.py

TEMPLATES = [  
...  
'DIRS': [BASE_DIR+"/templates",],   # 修改位置  
#'DIRS': [os.path.join(BASE_DIR+"/templates",)],     #或是寫成這樣 
    ...  
    ]

增長新對象,向模板提交數據:視圖文件 views.py

#coding=utf-8  
#from django.http import HttpResponse  
from django.shortcuts import render  
def hello(request):  
    context          = {}  
    context['hello'] = 'Hello World!'  
    return render(request, 'hello.html', context)  
    #return render(request, 'hello.html',{'HELLO':'這裏必須寫一個相對應的鍵值對'})

咱們這裏使用 render 來替代以前使用的 HttpResponse 對頁面進行渲染。值得一提的是,HttpResponse()不能將渲染的形式和和內容分離。不符合MVT的設計思惟。
context 字典中元素的鍵值 "hello" 對應了模板中的變量 "{{ hello }}"。

 

----------------後臺管理--------------------

內容發佈 和 公共訪問。

└─管理員:增刪改查數據

當初作的不少東西讓我以爲困惑。可我已經掌握瞭如何搭建Django項目,如今想來,只須要該一條HttpResponse響應語句就能夠了。

項目建立須要注意的一點是:

有過 PHP 編程背景的話,你可能習慣於將代碼都放在 Web 服務器的文檔根目錄 (例如 /var/www 這樣的地方)。而在 Django 中,你不能這樣作。把任何 Python 代碼放到 Web 服務器的文檔根目錄中都不是個好主意,由於這樣一來,你就要冒着別人透過頁面直接看到代碼的風險。這對於安全可不是件好事。把代碼放置在文檔根目錄以外的某些目錄中。

admin後臺站點管理工具

(部分參考Djangobook2.0第六章)

++管理界面++是某一類網站基礎設施中很是重要的一部分,因此咱們今天學習++Django的自動管理管理頁面++。
他的特性是:
從模型中讀取元數據,把他加載到到一個強大的管理頁面中,提供給網站管理者使用。
(請注意咱們建議你讀這章,即便你不打算用admin。由於咱們將介紹一些概念,這些概念能夠應用到Django的全部方面,而不只僅是admin)

  • 梗概:使用步驟
    1. 本地化管理界面(更改語言)
    2. 建立管理員
    3. 註冊模型類
    4. 發佈內容到數據庫
    5. 自定義站點管理界面

概念:django.contrib 包

Django管理工具是它的一部分,django.contrib是一套龐大的功能集。
(它是Django基本代碼的組成部分,Django框架就是由衆多包含附加組件(add-on)的基本代碼構成的。)
目前咱們只須要知道Django自帶不少優秀的附加組件,它們都存在於django.contrib包裏,如:
用戶鑑別系統(django.contrib.auth)、
支持匿名會話(django.contrib.sessioins)
以及用戶評註系統(django.contrib.comments)。

搭建步驟

1.激活管理工具:
[INSTALLED_APPS:]
確保包含這四個應用的存在:

'django.contrib.admin'  
'django.contrib.auth'  
'django.contrib.contenttypes'  
'django.contrib.sessions'  

[MIDDLEWARE_CLASSES:]  
含'django.middleware.common.CommonMiddleware'   'django.contrib.sessions.middleware.SessionMiddleware'  
'django.contrib.auth.middleware.AuthenticationMiddleware'

2.接下來進行數據庫遷移(歷史版本syncdb)
咱們還須要一個管理員,這個時候咱們建立一個超級用戶:
就須要運行這個命令 python manage.py createsuperuser,
輸入用戶名和密碼,郵箱不是必填的
(++值得一提的是:這命令是屬於'django.contrib.auth'這個模塊的++)
 

3.而後咱們把它填寫到URL路由中
須要確保from django.contrib import admin (後臺管理模塊)已經被導入。
[URL]:>urlpatterns:
++url(r'^admin/', include(admin.site.urls)),++

4.更改語言,使用admin管理工具

完成以上一系列配置以後,運行python manage.py runserver命令啓動服務器。
(界面管理的設計是針對非技術人員的,因此它是自我解釋的。)
因此咱們應該去setting中,能夠把管理界面相關的語言改爲咱們本身國家使用的語言,就好比中文的話:

LANGUAGE_CODE = 'zh-Hans'  
TIME_ZONE = 'Asia/Shanghai'  
USE_I18N = True  
USE_L10N = True  
USE_TZ = False

admin註冊模型類:admin.site.register

咱們++須要管理其餘的表++,須要將其餘的表添加到後臺管理工具中,++在admin.py中注++冊它。
概念:在Django管理頁面中,每一種數據類型都有一個 change list 和 edit form 。
(前者顯示數據庫中全部的可用對象;後者可以讓你添加、更改和刪除數據庫中的某條記錄。)
管理界面就是一個漂亮的表查詢和表操做界面,但每一條更改都會被記錄到歷史信息中。
在沒有添加應用、而且沒有在應用中添加models模型表的時候,咱們進行數據庫遷移是不須要python manage.py makemigrations(生成遷移)這條命令的,若是使用一下咱們就能看到系統的提示:No changes detected
(數據沒有更改)
admin.site.register 接受一個ModelAdmin子類做爲可選參數。用於控制模型類的顯示方式

自定義admin列表步驟> [admin.py:] - ModelAdmin是admin的子類

  1. 創建類
class AuthorAdmin(admin.ModelAdmin):
  1. 添加方法:
#例如:
list_display=('name','email','country')
(包含字段名稱的元組)
  1. 做爲參數被註冊
admin.site.register(Author,AuthorAdmin)

(以上操做不對數據庫形成更改)

自定義admin列表工具集[admin.py:]

--(管理界面不該容許公衆訪問和複雜排序,查詢;且僅提供給可信任的管理員)--

顯示指定字段

list_display=('name','email','country')
#接收包含字段名稱的元組
  • 添加根據姓名查詢的查詢框
search_fields=("name")
'''對大小寫敏感,且默認不支持外鍵
[解決辦法]:字段名+雙下劃線+屬性名,例如:
search_field=('author_name')
'''
  • 根據做者、時間查詢的過濾器
list_filter("author","time")
#支持布爾型,外鍵,多個字段
  • 添加一個時間導航條
date_hierarchy='time'
只支持時間類型的字段
  • 添加排序
ordering=("-time","name")
#經過時間來排序name
#只支持元祖類型參數
  • 改變字段的排列順序
fields=("time","name")
'''他能夠用來開放/關閉可編輯的字段,只須要不填寫便可,同時:
系統會將他設置爲None(必須符合null=True約束)
目前爲止,除了搜索欄,其餘都支持外鍵'''
  • 內聯(或稱關聯)
#----編輯和添加頁面的效果,它更復雜一些-----
#1.建立鏈接類(表格效果)
class BookInline(admin.TabularInline):
    model=Book  #(外鍵表名)
    extra = 3   #(限制可更改屬性的數量上限)
#2.在管理類中建立鏈接
classAuthorAdmin(admin.ModelAdmin):
    **lines=[BookInlines]**     #主要是這一步,但兩步缺一不可
#還有第二種實現方法,但實現效果有略微區別,咱們須要改成繼承停靠方法
#1.建立鏈接類
class BookInline(admin.StackedInline):
    model=Book  #(外鍵表名)
    extra = 3   #(限制屬性的數量上限)
#2.在管理類中建立鏈接
classAuthorAdmin(admin.ModelAdmin):
    **lines=[BookInlines]**
#除了類名和顯示效果略微不一樣外,其餘使用效果徹底相同
  • 下側分頁
list_per_page = 1
# 一頁只顯示1條數據
  • 將屬性分組
# ----應用於添加頁面和管理頁面的效果----
# 主要是一個json格式看起來更復雜
# 他的鍵名是能夠自定義的,你能夠隨便定義鍵名用做組名
fieldsets = [
('basic',{'field':['btitle']}),
('more',{'field':['bpub_date']}),
]
  • 屬性的前後順序
# ----應用於添加頁面和管理頁面的效果-----
field = ['bpub_date','btitle']

表單

(部分參考於Djangobook2.0第七章)

從Google的簡樸的單個搜索框,到常見的Blog評論提交表單,再到複雜的自定義數據輸入接口,HTML表單一直是交互性網站的支柱。 本章介紹如何用Django對用戶經過表單提交的數據進行訪問、有效性檢查以及其它處理。 與此同時,咱們將介紹++HttpRequest對象++和++Form對象++。

HttpRequest對象包含當前請求URL的一些信息:

屬性/方法   說明  舉例
request.path    除域名之外的請求路徑,以正斜槓開頭   "/hello/"
request.get_host()  主機名(好比,一般所說的域名)     "127.0.0.1:8000" or "www.example.com"
request.get_full_path()     請求路徑,可能包含查詢字符串  "/hello/?print=true"
request.is_secure()     若是經過HTTPS訪問,則此方法返回True, 不然返回False   True 或者 False

request.META

request.META 是一個Python字典,包含了全部本次HTTP請求的Header信息,好比用戶IP地址和用戶Agent(一般是瀏覽器的名稱和版本號)。
如下是常見的鍵值:

HTTP_REFERER,進站前連接網頁,若是有的話。 (請注意,它是REFERRER的筆誤。)
11

HTTP_USER_AGENT,用戶瀏覽器的user-agent字符串,若是有的話。 例如: "Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17" .

REMOTE_ADDR 客戶端IP,如:"12.345.67.89" 。(若是申請是通過代理服務器的話,那麼它多是以逗號分割的多個IP地址,如:"12.345.67.89,23.456.78.90" 。)

值得一提的是:注意,由於 request.META 是一個普通的Python字典,所以當你試圖訪問一個不存在的鍵時,會觸發一個KeyError異常。 (HTTP header信息是由用戶的瀏覽器所提交的、不該該給予信任的「額外」數據,所以你老是應該好好設計你的應用以便當一個特定的Header數據不存在時,給出一個優雅的迴應。)你應該用 ++try/except++ 語句,++或者用Python字典的 get() 方法++來處理這些「可能不存在的鍵」

  1. 今天總結了幾個寫登錄註冊時候的注意事項,這是我經常忽略的。我常常忘記在input輸入框外面套form(表單)標籤。————總結下緣由,實際上是本身對於內部運行機制的掌握不熟練所致的。
  2. 第二個常犯的錯誤就是老是忘記在form(post請求方式)標籤內添加{% csrf_token%,致使服務器運行起來的時候,瀏覽器會返回403錯誤。
  3. 第三個出現的錯誤就是,會遺忘在運行服務器以前把數據庫遷移,致使註冊頁面的信息沒法導入數據庫。下次遷移記得加。愛你。

Django的認證系統

Django認證系統,包含了身份驗證和權限管理兩部分。簡單地說,身份驗證用於覈實某個用戶是否合法,權限管理則是決定一個合法用戶具備哪些權限。日後,‘認證’這個詞同時代指上面兩部分的含義。

1、用戶與分組-User & Group

  • 建立用戶:
from django.contrib.auth.models import User
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
  user = User.objects.create_user(username="zhaoyingwei",password="123")
  return HttpResponse('用戶建立成功')
  • 修改密碼:
def index(request):
  u = User.objects.get(username='python')
  u.set_password('321')
  return HttpResponse('密碼修改爲功')
  • 用戶驗證:
from django.contrib.auth import authenticate
def index(request):
  user = authenticate(username='python', password='321')
  if user:
    return HttpResponse('驗證經過')
  • 組的建立:
#coding=utf-8  
from django.contrib.auth.models import Group
from django.contrib.auth.models import User
def index(request):
  group = Group.objects.create(name=group_name)
  group.save()
  return HttpResponse('組建立成功')
  • 用戶添加到組:
def index(request):
  group = Group.objects.get(name = '第一組')
  user = User.objects.get(username="zhaoyingwei", password="123")
  user.groups.add(group)
  return HttpResponse('ok')
  • 用戶加入用戶組
user.groups.add(group)
group.user_set.add(user)
  • 用戶退出用戶組
user.groups.remove(group)
group.user_set.remove(user)
  • 用戶退出全部用戶組
user.groups.clear()
  • 用戶組中全部用戶退出組
group.user_set.clear()
  • 登陸
    login向session中添加SESSION_KEY, 便於對用戶進行跟蹤:
    login不進行認證,也不檢查is_active標誌位, 通常和authenticate配合使用:
from django.contrib.auth import login
user = authenticate(username=username, password=password)
if user is not None:
    if user.is_active:
        login(request, user)
在auth/__init__.py中能夠看到login的源代碼。
  • 退出登陸
logout會移除request中的user信息, 並刷新session:
from django.contrib.auth import logout
def logout_view(request):
    logout(request)
  • 權限判斷,只容許登陸用戶訪問
@login_required修飾器修飾的view函數會先經過session key檢查是否登陸, 
已登陸用戶能夠正常的執行操做, 未登陸用戶將被重定向到login_url指定的位置。
若未指定login_url參數, 則重定向到settings.LOGIN_URL。
from django.contrib.auth.decorators import login_required
@login_required(login_url='/accounts/login/')
def my_view(request):

2、權限-Permission

Django的auth系統提供了模型級的權限控制
便可以檢查用戶是否對某個數據表擁有增(add), 改(change), 刪(delete)權限。

  • auth系統沒法提供對象級的權限控制,即檢查用戶是否對數據表中某條記錄擁有增改刪的權限。
    假設:在博客系統中有一張article數據表管理博文,
    auth能夠檢查某個用戶是否擁有對全部博文的管理權限,
    但沒法檢查用戶對某一篇博文是否擁有管理權限。
  • 若是須要對象級權限控制可使用django-guardian。

  • 檢查用戶權限:
    user.has_perm方法用於檢查用戶是否擁有操做某個模型的權限:

user.has_perm('blog.add_article')
user.has_perm('blog.change_article')
user.has_perm('blog.delete_article')

'''上述語句檢查用戶是否擁有blog這個app中article模型的添加權限, 若擁有權限則返回True。  
has_perm僅是進行權限檢查, 便是用戶沒有權限它也不會阻止程序員執行相關操做。並且無關於該用戶是否離職。'''

示例:

from django.contrib.auth.models import User
from django.contrib.auth import authenticate
def index(request):
    user = authenticate(username='lucy', password='123')
  if user.has_perm('booktest.add_bookinfo'):
    return HttpResponse('用戶擁有這個權限')
  else:
    return HttpResponse('沒有權限')

from django.contrib.auth import authenticate
from django.contrib.auth.models import Permission, User
def index(request):
  Permission.objects.create(name='角色管理',content_type_id=7,codename='權限管理描述')
  perm = Permission.objects.get(name='角色管理')
  User.objects.get(username='zhaoyingwei').user_permissions.add(perm)
  return HttpResponse('ok')

@permission_required裝飾器

  • 能夠代替has_perm並在用戶沒有相應權限時重定向到登陸頁或者拋出異常。
  • 每一個模型默認擁有增(add), 改(change), 刪(delete)權限。
  • 在django.contrib.auth.models.Permission模型中保存了項目中全部權限。
    該模型在數據庫中被保存爲auth_permission數據表。
permission_required(perm[, login_url=None, raise_exception=False])

@permission_required('blog.add_article')
def post_article(request):
    pass
  • 管理用戶權限
User和Permission經過多對多字段user.user_permissions關聯,
在數據庫中由auth_user_user_permissions數據表維護。
  • 添加權限
user.user_permissions.add(permission)
  • 刪除權限:
user.user_permissions.delete(permission)
  • 清空權限:

用戶擁有他所在用戶組的權限, 使用用戶組管理權限是一個更方便的方法。
Group中包含多對多字段permissions, 在數據庫中由auth_group_permissions數據表維護。

user.user_permissions.clear()
  • 添加權限:
group.permissions.add(permission)
  • 刪除權限:
group.permissions.delete(permission)
  • 清空權限:
group.permissions.clear()
  • 自定義權限:
    在定義Model時可使用Meta自定義權限:
class Discussion(models.Model):
  ...
  class Meta:
      permissions = (
          ("create_discussion", "Can create a discussion"),
          ("reply_discussion", "Can reply discussion"),
      )
  • 判斷用戶是否擁有自定義權限:
user.has_perm('blog.create_discussion')
  • 添加權限:
Permission.objects.create(name=u'權限管理',content_type_id=2,codename=u'權限管理描述')
  • 添加用戶權限:
perm = Permission.objects.get(codename=u'權限管理')#首先你須要添加"權限管理"這項權限
User.objects.get(username='270001').user_permissions.add(perm)
  • 刪除用戶權限:
perm = Permission.objects.get(codename=u'權限管理')#首先你須要添加"權限管理"這項權限
User.objects.get(username='270001').user_permissions.remove(perm)
  • 批量添加用戶權限:
perm1 = Permission.objects.get(codename=u'權限管理')
perm2 = Permission.objects.get(codename=u'用戶管理')
User.objects.get(username='270001').user_permissions.add(perm1,perm2)
  • 清空用戶權限:
User.objects.get(username='270001').user_permissions.clear()
  • 查詢用戶權限,並輸出
c = User.objects.get(username='270001').user_permissions.values()
for i in c:
    print i

分頁系統 Paginator

  • Django提供了一個新的類來幫助你管理分頁數據,這個類存放在django/core/paginator.py.它能夠接收列表、元組或其它可迭代的對象。
#源碼
class Paginator(object):
    def __init__(self, object_list, per_page, orphans=0,
                 allow_empty_first_page=True):
        self.object_list = object_list
        self._check_object_list_is_ordered()
        self.per_page = int(per_page)
        self.orphans = int(orphans)
        self.allow_empty_first_page = allow_empty_first_page
  • 實例:
  • 生成對象前導入模塊
from django.core.paginator import Paginator
objects = ['a','b','c','d','e','f','g','h','i','j']
  • 實例化分頁對象:以3爲距離單位切割對象(仍保留所有完整數據)
p = Paginator(objects,3)
  • 查看對象元素總數(10個)
p.count
  • 查看對象分紅了幾頁(4頁)
p.num_pages
  • 查看對象的可迭代範圍
p.page_range
#這裏返回:xrange(1,5)
  • 取對象的第一分頁對象
page1 = p.page(1) 
# 我這裏輸出:<Page 1 of 10>
  • 第一分頁對象的元素列表['john', 'paul', 'george']
page1.object_list
#這裏返回:['a', 'b', 'c']
  • 第一分頁對象的當前頁值 1
page1.number
  • 分頁對象是否有前一頁
page1.has_previous()
#False
  • 分頁對象是否有下一頁
page1.has_next()
#Ture
  • 對象是否有其它頁
page1.has_other_pages()
#True
  • 分頁對象下一頁碼的值
page1.next_page_number()
  • 分頁對象的上一頁碼值
page1.previous_page_number()
  • 分頁對象的元素開始索引
page2.start_index()
  • 分頁對象的元素結束索引
page2.end_index()
  • 模板系統會爲咱們自動添加函數後面的括號,好比讓我很困惑的page1.has_previous 和 page1.has_previous()

數據格式json(data.json)

  • json是一個數據格式:全稱JavaScript Object Notation (Js對象表示)
  • json與XML:json在逐漸取代XML
    json格式數據:
{
    "name":'tom',
    "age":18
    "info":["male","engineer"]
}

與json對象不一樣的是,json數據格式的屬性名稱(Key)須要用雙引號引發來,用單引號或者不用引號會致使讀取數據錯誤。

json的另一個數據格式是數組,和javascript中的數組字面量相同。

['tom',18,'programmer']

ajax與jsonp

ajax的目的是讓JavaScript發送http請求,與後臺通訊,獲取數據和信息
ajax是被吹上天了的一個技術,讓人看看不清它的本質。
同步與異步
程序中的同步和異步與現實生活中的同步和異步是對調的。異步是能夠同時作幾件事情。
局部刷新與無刷新
ajax能夠是實現局部刷新,也叫作無刷新。無刷新
同源策略
ajax爲了安全性的須要,它只能請求同一個域下面或組域和子域的內容。例如阿里的ajax不能請求騰訊的數據。
(在服務器環境裏才能讀)

admin後臺站點管理工具,部分參考Djangobook2.0第六章

++管理界面++是某一類網站基礎設施中很是重要的一部分,因此咱們今天學習++Django的自動管理管理頁面++。
他的特性是:
從模型中讀取元數據,把他加載到到一個強大的管理頁面中,提供給網站管理者使用。
(請注意咱們建議你讀這章,即便你不打算用admin。由於咱們將介紹一些概念,這些概念能夠應用到Django的全部方面,而不只僅是admin)

梗概:使用步驟

  1. 本地化管理界面(更改語言)
  2. 建立管理員
  3. 註冊模型類
  4. 發佈內容到數據庫
  5. 自定義站點管理界面

概念:django.contrib

Django管理工具是它的一部分,django.contrib是一套龐大的功能集。
(它是Django基本代碼的組成部分,Django框架就是由衆多包含附加組件(add-on)的基本代碼構成的。)
目前咱們只須要知道Django自帶不少優秀的附加組件,它們都存在於django.contrib包裏,如:
用戶鑑別系統(django.contrib.auth)、
支持匿名會話(django.contrib.sessioins)
以及用戶評註系統(django.contrib.comments)。

搭建步驟

1.激活管理工具:
[INSTALLED_APPS:]
確保包含這四個應用的存在:
'django.contrib.admin'
'django.contrib.auth'
'django.contrib.contenttypes'
'django.contrib.sessions'
 
[MIDDLEWARE_CLASSES:]
含'django.middleware.common.CommonMiddleware' 'django.contrib.sessions.middleware.SessionMiddleware'
'django.contrib.auth.middleware.AuthenticationMiddleware'
 

2.接下來進行數據庫遷移(歷史版本syncdb,再也不贅述)
可是咱們還須要一個管理員,這個時候咱們建立一個超級用戶:
咱們就須要運行這個命令 python manage.py createsuperuser,
輸入用戶名和密碼,郵箱不是必填的
(++值得一提的是:這命令是屬於'django.contrib.auth'這個模塊的++)
 

3.而後咱們把它填寫到URL路由中
須要確保from django.contrib import admin (後臺管理模塊)已經被導入。
[URL]:>urlpatterns:
++url(r'^admin/', include(admin.site.urls)),++

4.更改語言,使用admin管理工具

完成以上一系列配置以後,運行python manage.py runserver命令啓動服務器。
(界面管理的設計是針對非技術人員的,因此它是自我解釋的。)
因此咱們應該去setting中,能夠把管理界面相關的語言改爲咱們本身國家使用的語言,就好比中文的話:

LANGUAGE_CODE = 'zh-Hans'  
    TIME_ZONE = 'Asia/Shanghai'  
    USE_I18N = True  
    USE_L10N = True  
    USE_TZ = False

admin註冊模型類:admin.site.register

咱們++須要管理其餘的表++,須要將其餘的表添加到後臺管理工具中,++在admin.py中注++冊它。
概念:在Django管理頁面中,每一種數據類型都有一個 change list 和 edit form 。
(前者顯示數據庫中全部的可用對象;後者可以讓你添加、更改和刪除數據庫中的某條記錄。)
管理界面就是一個漂亮的表查詢和表操做界面,但每一條更改都會被記錄到歷史信息中。
在沒有添加應用、而且沒有在應用中添加models模型表的時候,咱們進行數據庫遷移是不須要python manage.py makemigrations(生成遷移)這條命令的,若是使用一下咱們就能看到系統的提示:No changes detected
(數據沒有更改)

admin.site.register 接受一個ModelAdmin子類做爲可選參數。用於控制模型類的顯示方式

自定義admin列表步驟> [admin.py:] - ModelAdmin是admin的子類

  1. 創建類
class AuthorAdmin(admin.ModelAdmin):
  1. 添加方法:
#例如:
    list_display=('name','email','country')
    (包含字段名稱的元組)
  1. 做爲參數被註冊
admin.site.register(Author,AuthorAdmin)

(以上操做不對數據庫形成更改)

自定義admin列表工具集[admin.py:]
--(管理界面不該容許公衆訪問和複雜排序,查詢;且僅提供給可信任的管理員)--

顯示指定字段

list_display=('name','email','country')
#接收包含字段名稱的元組

添加根據姓名查詢的查詢框

search_fields=("name")
'''對大小寫敏感,且默認不支持外鍵
[解決辦法]:字段名+雙下劃線+屬性名,例如:
search_field=('author_name')
'''

根據做者、時間查詢的過濾器

list_filter("author","time")
#支持布爾型,外鍵,多個字段

添加一個時間導航條

date_hierarchy='time'
只支持時間類型的字段

添加排序

ordering=("-time","name")
#經過時間來排序name
#只支持元祖類型參數

改變字段的排列順序

fields=("time","name")
'''他能夠用來開放/關閉可編輯的字段,只須要不填寫便可,同時:
系統會將他設置爲None(必須符合null=True約束)
目前爲止,除了搜索欄,其餘都支持外鍵'''

內聯

#在編輯頁面的效果,它更復雜一些
    #1.建立鏈接類
    class BookInline(admin.TabularInline):
        model=Book  #(外鍵表名)
    #2.在管理類中建立鏈接
    classAuthorAdmin(admin.ModelAdmin):
        **lines=[BookInlines]**     #主要是這一步,但兩步缺一不可

百科

URL

URL(統一資源定位符)全稱是UniformResourceLocator,是互聯網上用來標識某一處資源的地址。
包含了用於查找某個資源的足夠的信息。 URL分爲七個部分:
(詳解URL組成原文:http://blog.csdn.net/ergouge/1article/details/8185219 )

1.協議 2.域名 3.端口 4.虛擬目錄 5.文件名 6.錨 7.參數

觸發出錯:

assert False 來觸發出錯頁。 而後,你就能夠看到局部變量和程序語句了。
__name__:意爲當前目錄。)

Markdown

  • Markdown能夠解析前端標籤。我剛纔打算展現前端頁面的源代碼,少寫了一個回車,他竟然直接給我渲染出來了。

CBV與FBV:

  • 分別是基於類的視圖和基於函數的視圖。

什麼是 BSD 協議?

BSD開源協議是一個給於使用者很大自由的協議。能夠自由的使用,修改源代碼,也能夠將修改後的代碼做爲開源或者專有軟件再發布。當你發佈使用了BSD協議的代碼,或者以BSD協議代碼爲基礎作二次開發本身的產品時,須要知足三個條件:
若是再發布的產品中包含源代碼,則在源代碼中必須帶有原來代碼中的BSD協議。
若是再發布的只是二進制類庫/軟件,則須要在類庫/軟件的文檔和版權聲明中包含原來代碼中的BSD協議。
不能夠用開源代碼的做者/機構名字和原來產品的名字作市場推廣。
BSD代碼鼓勵代碼共享,但須要尊重代碼做者的著做權。BSD因爲容許使用者修改和從新發布代碼,也容許使用或在BSD代碼上開發商業軟件發佈和銷 售,所以是對商業集成很友好的協議。
不少的公司企業在選用開源產品的時候都首選BSD協議,由於能夠徹底控制這些第三方的代碼,在必要的時候能夠修改或者 二次開發。

在pycharm中配置端口

  • IP:http://www.mamicode.com/info-detail-1647386.html

render的參數local():

  • 魯莽選擇(它會選擇函數中全部的字段所有傳到前端)

has_key()函數的使用:

  • 在python3中已經移除該方法,改用in來查詢字典是否擁有某個鍵值。

一些建立數據模型的參考:

  • 書籍:標題(book_title),出版時間(book_pub_date),閱讀量(b_read),書籍信息(book_comment),邏輯刪除(isDelete)
  • 英雄:姓名(hero_name),性別(hero_gender),描述()

通用視圖
切勿退出裝飾器
│命名空間

一些假數據(用於測試):

  • 模型BookInfo的測試數據
insert into book(b_title,b_pub_date,b_read,b_commet,isDelete) values
('射鵰英雄傳','1980-5-1',12,34,0),
('天龍八部','1986-7-24',36,40,0),
('笑傲江湖','1995-12-24',20,80,0),
('雪山飛狐','1987-11-11',58,24,0);
  • 模型HeroInfo的測試數據
insert into modelapp_heroinfo(h_name,h_gender,h_book_id,h_content,isDelete) values
('郭靖',1,1,'降龍十八掌',0),
('黃蓉',0,1,'打狗棍法',0),
('黃藥師',1,1,'彈指神通',0),
('歐陽鋒',1,1,'蛤蟆功',0),
('梅超風',0,1,'九陰白骨爪',0),
('喬峯',1,2,'降龍十八掌',0),
('段譽',1,2,'六脈神劍',0),
('虛竹',1,2,'天山六陽掌',0),
('王語嫣',0,2,'神仙姐姐',0),
('令狐沖',1,3,'獨孤九劍',0),
('任盈盈',0,3,'彈琴',0),
('嶽不羣',1,3,'華山劍法',0),
('東方不敗',0,3,'葵花寶典',0),
('胡斐',1,4,'胡家刀法',0),
('苗若蘭',0,4,'黃衣',0),
('程靈素',0,4,'醫術',0),
('袁紫衣',0,4,'六合拳',0)

學習Django內部原理筆記

在這裏安裝過的應用,本質其實都是對Python包的引入。咱們均可以在目錄中找到這些應用的位置。

image

看一下,就是這個socail_dango也是能夠找到的。(它是第三方包)

這裏的social_core並無在應用中安裝。

今天我誤把AUTHENTICATION_BACKENDS看成了中間件,直到它報了不少錯誤。我才發現個人
social_core.backends.weibo.Weibo 不該該放在MIDDLEWARE配置列表中。可是我學習了不少中間件的知識:

其實配置中間件的本質也就是經過訪問文件夾路徑來引入Python包中的一個個中間件,也就是類。(它們就是用於提供各類各樣的特殊的功能)。

返回目錄

日誌管理

第三方登陸

-返回目錄-

Celery異步加載首先須要安裝第三方協程包

操做系統:win10

  • 安裝Celery
pip install celery
  • windows須要安裝第三方協程包
pip install eventlet
  • 創建一個task.py 文件
    這個文件會被celery添加到任務隊列中,當調用該文件的命令信號發送到celery時,該文件的內容會被執行。
    同時,當須要其餘的異步功能時,能夠再寫新的py腳本,將他們都添加到任務隊列中。

位置:項目下/Celery_tasks/task.py

from celery import Celery
import os

broker_url = "redis://127.0.0.1:6379/14"
result_backend = "redis://127.0.0.1:6379/15"
app = Celery('tasks', broker=broker_url, backend=result_backend)


from yunpian_python_sdk.model import constant as YC
from yunpian_python_sdk.ypclient import YunpianClient
apikey = '846bd5453a038f21d779130c672046b0'


@app.task(name='send_sms_code')  # 給任務取一個名字,通常就是函數名字
def send_sms_code(mobile, sms_code):
    clnt = YunpianClient(apikey)
    param = {YC.MOBILE: mobile, YC.TEXT: '【雲片網】您的驗證碼是%s' % sms_code}
    r = clnt.sms().single_send(param)
    print(r.code(), r.data())
  • 啓用celery

使用命令調用該文件,將其添加到任務隊列。
enventlet 就是剛纔咱們安裝的windows協程包。
將它交給運行器(worker)來等待處理。

Celery -A ./celery/task worker -l info -P eventlet

成功的運行結果
成功後的運行結果

何時觸發運行?

當celery被咱們開啓以後,它會一直等待消息命令的傳入,也就是說,這是能夠屢次觸發,屢次運行的。

  • 在Views中這樣寫:
from celery_tasks.tasks import send_sms_code
        send_sms_code.delay(mobile, sms_code)           # 使用celery異步任務發送短信
  • 上一張配圖

返回目錄

電商中什麼是SPU 和SKU?

在電商中對於商品,有兩個重要的概念:SPU和SKU

先看一段很是長的介紹

  • SPU = Standard Product Unit (標準產品單位)

SPU是商品信息聚合的最⼩小單位,是⼀一組可服⽤用、易易檢索的標
準化信息的集合,該集合描述了了⼀一個產品的特性。
通俗的講,屬性值、特性相同的商品就能夠稱爲⼀一個SPU。
例例如:
iPhone X 就是⼀一個SPU,與商家、顏⾊色、款式、規格、套餐等
都⽆無關。

  • SKU = Stock Keeping Unit (庫存量量單位)

SKU即庫存進出計量量的單位,能夠是以件、盒、托盤等爲單位,
是物理理上不不可分割的最⼩小存貨單元。在使⽤用時要根據不不同業態,
不不同管理理模式來處理理。在服裝、鞋類商品中使⽤用最多最廣泛。
例例如:
iPhone X 全⽹網通⿊黑⾊色256G 就是⼀一個SKU,表示了了具體的規
格、顏⾊色等信息。

相信你們看完了剛纔的介紹,確定仍是蒙的,你說的這是啥?
不要緊,不用看剛纔那兩段話也能明白這兩個概念。

還有兩個圖供你們選擇:第一個圖適合未成年人觀看。

第二個圖也適合未成年人觀看。我本身畫的,醜可是很容易懂。

-返回目錄-

CKEditor 富文本編輯器

使用聖堂法術DRF進行接口開發

連接:點擊這裏就不會錯過青魔法聖堂法術 DRF (Django REST framework) 框架(持續更新)
連接:更多請關注個人青魔法Python

**我是文章結尾,點我跳轉到文章開頭再看看**

相關文章
相關標籤/搜索