title: 青魔法聖堂法術
tags: ,模板,小書匠,Python-高階法術
grammar_cjkRuby: true
---javascript
**跳轉到文章結尾**
連接:https://www.cnblogs.com/Asterism-2012/p/10046765.html#headhtml
日誌管理前端
第三方登錄java
使用聖堂法術DRF進行接口開發python
Celery異步加載
mysql
django是一個web框架。(音標:[dʒæŋɡoʊ])ajax
Django用於快速開發數據驅動網站。他幾乎爲咱們封裝好了開發站點所須要作的一切冗餘操做。(避免重複造輪子,而且無需瞭解與服務器溝通的過程)
就像是咱們只須要製做玩具車的零件,Django框架爲咱們作好須要生產出一個玩具車的一切。
(在學習此課程以前,咱們要確保咱們電腦上已經安裝了所需的Python、Django、Mysql等環境,框架,數據庫而且配置好相關的環境變量)
Django的發佈時間是:2005年。
——學習Web開發很差好學習HTTP報文,將會「打拳不練功,到老一場空」,你花在犯迷糊上的時間比你沉下心來學習HTTP的時間確定會多不少。
(HTTP報文解釋:https://blog.csdn.net/zhll3377/article/details/7748086)
學習Django入門的兩個步驟:
Web框架爲應用程序提供了一套程序框架,這樣你能夠++專一++於編寫清晰、易維護的代碼,++而無需從頭作起。++ 簡單來講,這就是Django所能作的。
Django學習的三個參考:1.Django官網,2.Django源碼——Github,3.官方文檔(參考自傳智播客)
閱讀【django源碼】
(1)核心思想:解耦。
++下降++模塊之間的++耦合++,加強擴展性和移植性。而且向後版本兼容。
鬆散的三部分組合在一塊兒就是模型-視圖-控制器(MVC)的設計模式。簡單的說,++MVC++是一種++軟件開發的方法++,它把:
a. 代碼的定義和數據訪問的方法(模型)與
b. 請求邏輯 (控制器)還有
c. 用戶接口(視圖)這三部分分離開來。
(2)開發原則:高內聚,低耦合。
高內聚的意思是,邏輯嚴謹,經過繼承體現。
MVC解析:1.Model:封裝對數據庫的訪問,內嵌ORM框架。
核心思想:解耦。
開發原則:高內聚,低耦合。
MVC解析:
內聚性:功能強度的度量,經過繼承體現(語名間,程序段間)模塊內部個元素彼此的緊密程度(邏輯性)。
耦合性(coupling):耦合高低取決於模板間接口的複雜性,調用的方式以及傳遞的信息。耦合性也叫塊間聯繫。指軟件系統結構中各模塊間相互聯繫緊密程度的一種度量。模塊之間聯繫越緊密,其耦合性就越強,模塊之間越獨立則越差。耦合性就是模塊與模塊之間的親密關係,關係親密則依賴度高,若不然易於移植和拓展。
爲何使用虛擬環境? 搭建獨立python運行環境。防止相同包的不一樣版本之間相互衝突和覆蓋.
MVT丟掉Template,依然能夠進行數據請求(交互),Ajax請求用json進行交互.這體現瞭解耦(先後端分離).
Django爲咱們準備了一個輕量級的Web開發服務器。僅用於開發階段使用。
(Py_Django2.0.6) E:\Git\demo_project>python manage.py runserver
pip install django==2.0.6
import django django.get_version()
(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
先看一下表結構:
卷 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
包。__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
文件配置介紹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中添加應用的作法能夠叫作安裝應用, 也能夠叫作註冊應用。
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 是一個django自身支持的數據庫
開發流程綱要:
Models.py
說明:
- 排序會增長數據庫的開銷:在磁盤的物理佔用會變大
- 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語句。(除非你是一個業餘愛好者,不然其實仍是要懂的,程序員不懂不行啊)。
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不一樣,它是面向用戶的。
class Meta:
class Meta: db_table='新的數據表名稱'
class BookInfo(models.Model): ... class Meta(): ordering = ['id'] # 字符串前加-表示倒序,不加-表示正序 class BookInfo(models.Model): ... class Meta(): ordering = ['-id'] # 表示倒序排序
class BookInfo(models.Model): ... books = models.Manager() #注意,當咱們這樣作的時候。默認的object就沒了 books1 = models.Mnager() #這樣作咱們就要能夠擁有多個管理器 #可是以上代碼這樣寫是沒有意義的
改變默認查詢集的結果,改變建立方法
設置模型類的建立
'''咱們要經過本身定義的管理器的類繼承Manager,經過重寫++get_queryset++方法來完成更改默認查詢集''' class BookInfoManager(models.Manager): def get_queryset(self): return super(BookInfoManager,self).get_queryset().filter(isDelete=False)
hero = HeroInfo() hero.hero_name = '俄狄浦斯' hero.save()
這一個概念是基礎概念,很容易理解,可是要須要多多實際練習。
- 關係的類型包括
- ForeignKey:一對多,將字段定義在多的一段端中(就是在子級表中定義一個字段指向父級表),就是外鍵。例如一本書中有多個英雄,在英雄表中定義「書籍字段」,指向該英雄所對應的書籍。
- ManyToManyField:多對多,將字段定義在兩端中 。例如朋友與朋友之間,就是多對多,你能夠是他們的朋友,他們也有本身的朋友。
- OneToOneField:一對一,將字段定義在任意一端中。好比身份證,一我的只能有一張身份證。
- 能夠維護遞歸的關聯關係,使用'self'指定,詳見「自關聯」
- 跨表的字段存儲的原理就是至關於一個指針,存儲對方的主鍵。相似於蟲洞穿越。
三種關係之間訪問方式:
bookinfo.heroinfo_set
heroinfo.bookinfo
heroinfo.book_id
Views.py
所謂的視圖函數(或 視圖 ),只不過是一個接受 Web 請求並返回 Web 響應的 Python 函數。實際上,該響應能夠是++一份網頁的 HTML 內容、一次重定向、一條 404 錯誤、一份 XML 、文檔、一幅圖片,或其它任何東西++。視圖自己包含返回該響應所需的任意邏輯。
視圖的本質就是函數。
http://www.itcast.cn/python/1/?i=1&p=new,只匹配「/python/1/」部分
url(r'^([0-9]+)/$', views.detail, name='detail'),
url(r'^(?P<id>[0-9]+)/$', views.detail, name='detail'),
(用於反向解析)
主路由 url(r'^', include('booktest.urls', namespace='booktest')), 子路由 url(r'^([0-9]+)/$', views.detail, name='detail'),
(當關閉調試模式,DEBUG=False時候纔會啓用,同時要開放訪問)
... 找不到{{request_path}}這個路徑 </body> </html>
封裝了全部請求報文。
QueryDict對象是一個類字典的對象,它的特色是:它也是以鍵值對的形式保存數據,可是它的每個鍵均可以包括一個或多個值。也能夠這麼說:它的鍵是能夠重複的。
request.GET.get('鍵',default) request.POST.get('鍵',default) 或簡寫爲 request.get['鍵'] request.get['鍵]
request.get.getlist('鍵',default) request.POST.getlist('鍵',default)
在本網站中不用特地指定域名。
是咱們須要返回的一個對象。
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-type:指定輸出的MIME類型(多媒體文件後綴名類型如.html.py等:表示爲"text/html")
write(content):以文件的方式寫
response.write(任何格式的數據類型)
寫一個cookie返回給瀏覽器:
response = HttpResponse() response.set_cookie('鍵','值') #在這以後,它會保存至多兩週,而且在當前域名下會自動加入到請求頭部(request headers)中
在服務器端接收cookie:
#獲取cookie對象 cookie = request.COOKIE if cookie.has_key
cookie對象是區別於網站的,應用於當前域名內全部頁面。
出於安全考慮,是瀏覽器提供的限定,它隔離不一樣的網站。
例子:京東與淘寶的推薦。沒法相互讀取cookie信息。
cookie = request.COOKIE
#cookie對象 cookie['鍵'] #或者 cookie
#這是python2中的寫法 cookie.has_key('鍵') #Python3是這樣寫的 if '鍵' in cookie
response = HttpResponse('ok') response.delete_cookie('hello') return response
告訴瀏覽器從新發送請求
JsonResponse的默認Content-Type爲application/json
from django.http import JsonResponse
def index2(requeset):
return JsonResponse({'list': 'abc'})
session的值默認存在數據庫裏
在setting中註冊session應用(通常是默認添加的),而且添加中間件:
INSTALL_APP=[
...
'django.contrib.session',
]
MIDDLEWARE_CLASSES=[
...
'django.contrib.sessions.middleware.SessionMiddleware',
]
session對象賦值(假字典)
禁用會話:刪除上面指定的兩個值,禁用會話將節省一些性能消耗
session依賴於cookie;每一個cookie中都儲存着一個sessionid,用於和服務器中的session信息進行匹配。
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_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'
Django url()能夠接收四個參數,分別是兩個必選參數:regex、view 和++兩個可選參數++:kwargs、name,接下來詳細介紹這四個參數。
路由(routing)是指分組從源到目的地時,決定端到端路徑的網絡範圍的進程 [1]。
路由是指路由器從一個接口上收到數據包,根據數據包的目的地址進行定向並轉發到另外一個接口的過程。
路由工做包含兩個基本的動做:
一、肯定最佳路徑
二、經過網絡傳輸信息
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 建立超級用戶
QuerySet 能夠被構造,過濾,切片,作爲參數傳遞,這些行爲都不會對數據庫進行操做。只要你查詢的時候才真正的操做數據庫。(更多相關: https://blog.csdn.net/com_ma/article/details/79113291)
manage.py 生成應用多了[auth]、[contenttypes]、[sessions]、[staticfiles]
(詳情請參閱:https://blog.csdn.net/ldw220817/article/details/78575409)
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)
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)
(部分參考於Djangobook2.0)
模板就是定義一些咱們顯示的內容,一個模板能夠被多個視圖(Views)使用。
設置模板路徑,在settings.py中:
TEMPLATES = [loader.get_template(template_name),返回一個Template對象
Template對象的render(RequestContext)方法,使用context渲染模板
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))
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'})
包含:
模板繼承:爲了更好的可讀性,應該在{% block 名稱 %}{% endblock 名稱%}中填上名稱。
{{ variable}} <!--這裏寫變量名--!>
class BookInfo(models.Model): ... def tableName(): return verbpse_name ''' view: book=BookInfo.objects.all() templates: {{book.tableName}} '''
{% for ... in ...%} {% forloop.countrt %} {# 獲取循環索引值 #} {% forloop.countrt0 %} {# 從0開始獲取循環索引值 #} {% empty %} {# 若爲空 #} {% endfor %}
{% if... %} {% elif %} {% else %} {% endif %}
{% comment %} {% endcomment %}
{% url 'name' p1 p2 %} {% comment %}這裏的p1,p2是兩個參數{% endcomment %}
{% csrf_token %}{# 通常寫在form表單中,保護表單中的數據 #}
正向解析是給了一個地址咱們經過正則去匹配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 }}"。
----------------後臺管理--------------------
內容發佈 和 公共訪問。
│
└─管理員:增刪改查數據
有過 PHP 編程背景的話,你可能習慣於將代碼都放在 Web 服務器的文檔根目錄 (例如 /var/www 這樣的地方)。而在 Django 中,你不能這樣作。把任何 Python 代碼放到 Web 服務器的文檔根目錄中都不是個好主意,由於這樣一來,你就要冒着別人透過頁面直接看到代碼的風險。這對於安全可不是件好事。把代碼放置在文檔根目錄以外的某些目錄中。
(部分參考Djangobook2.0第六章)
++管理界面++是某一類網站基礎設施中很是重要的一部分,因此咱們今天學習++Django的自動管理管理頁面++。
他的特性是:
從模型中讀取元數據,把他加載到到一個強大的管理頁面中,提供給網站管理者使用。
(請注意咱們建議你讀這章,即便你不打算用admin。由於咱們將介紹一些概念,這些概念能夠應用到Django的全部方面,而不只僅是admin)
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)),++
完成以上一系列配置以後,運行python manage.py runserver命令啓動服務器。
(界面管理的設計是針對非技術人員的,因此它是自我解釋的。)
因此咱們應該去setting中,能夠把管理界面相關的語言改爲咱們本身國家使用的語言,就好比中文的話:
LANGUAGE_CODE = 'zh-Hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = False
咱們++須要管理其餘的表++,須要將其餘的表添加到後臺管理工具中,++在admin.py中注++冊它。
概念:在Django管理頁面中,每一種數據類型都有一個 change list 和 edit form 。
(前者顯示數據庫中全部的可用對象;後者可以讓你添加、更改和刪除數據庫中的某條記錄。)
管理界面就是一個漂亮的表查詢和表操做界面,但每一條更改都會被記錄到歷史信息中。
在沒有添加應用、而且沒有在應用中添加models模型表的時候,咱們進行數據庫遷移是不須要python manage.py makemigrations(生成遷移)這條命令的,若是使用一下咱們就能看到系統的提示:No changes detected
(數據沒有更改)
admin.site.register 接受一個ModelAdmin子類做爲可選參數。用於控制模型類的顯示方式。
自定義admin列表步驟> [admin.py:] - ModelAdmin是admin的子類
class AuthorAdmin(admin.ModelAdmin):
#例如: list_display=('name','email','country') (包含字段名稱的元組)
admin.site.register(Author,AuthorAdmin)
(以上操做不對數據庫形成更改)
--(管理界面不該容許公衆訪問和複雜排序,查詢;且僅提供給可信任的管理員)--
顯示指定字段
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 是一個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() 方法++來處理這些「可能不存在的鍵」
Django認證系統,包含了身份驗證和權限管理兩部分。簡單地說,身份驗證用於覈實某個用戶是否合法,權限管理則是決定一個合法用戶具備哪些權限。日後,‘認證’這個詞同時代指上面兩部分的含義。
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()
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):
Django的auth系統提供了模型級的權限控制,
便可以檢查用戶是否對某個數據表擁有增(add), 改(change), 刪(delete)權限。
若是須要對象級權限控制可使用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裝飾器
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()
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
#源碼 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']
p = Paginator(objects,3)
p.count
p.num_pages
p.page_range #這裏返回:xrange(1,5)
page1 = p.page(1) # 我這裏輸出:<Page 1 of 10>
page1.object_list #這裏返回:['a', 'b', 'c']
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()
{ "name":'tom', "age":18 "info":["male","engineer"] }
與json對象不一樣的是,json數據格式的屬性名稱(Key)須要用雙引號引發來,用單引號或者不用引號會致使讀取數據錯誤。
json的另一個數據格式是數組,和javascript中的數組字面量相同。
['tom',18,'programmer']
ajax的目的是讓JavaScript發送http請求,與後臺通訊,獲取數據和信息
ajax是被吹上天了的一個技術,讓人看看不清它的本質。
同步與異步
程序中的同步和異步與現實生活中的同步和異步是對調的。異步是能夠同時作幾件事情。
局部刷新與無刷新
ajax能夠是實現局部刷新,也叫作無刷新。無刷新
同源策略
ajax爲了安全性的須要,它只能請求同一個域下面或組域和子域的內容。例如阿里的ajax不能請求騰訊的數據。
(在服務器環境裏才能讀)
++管理界面++是某一類網站基礎設施中很是重要的一部分,因此咱們今天學習++Django的自動管理管理頁面++。
他的特性是:
從模型中讀取元數據,把他加載到到一個強大的管理頁面中,提供給網站管理者使用。
(請注意咱們建議你讀這章,即便你不打算用admin。由於咱們將介紹一些概念,這些概念能夠應用到Django的全部方面,而不只僅是admin)
梗概:使用步驟
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)),++
完成以上一系列配置以後,運行python manage.py runserver命令啓動服務器。
(界面管理的設計是針對非技術人員的,因此它是自我解釋的。)
因此咱們應該去setting中,能夠把管理界面相關的語言改爲咱們本身國家使用的語言,就好比中文的話:
LANGUAGE_CODE = 'zh-Hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = False
咱們++須要管理其餘的表++,須要將其餘的表添加到後臺管理工具中,++在admin.py中注++冊它。
概念:在Django管理頁面中,每一種數據類型都有一個 change list 和 edit form 。
(前者顯示數據庫中全部的可用對象;後者可以讓你添加、更改和刪除數據庫中的某條記錄。)
管理界面就是一個漂亮的表查詢和表操做界面,但每一條更改都會被記錄到歷史信息中。
在沒有添加應用、而且沒有在應用中添加models模型表的時候,咱們進行數據庫遷移是不須要python manage.py makemigrations(生成遷移)這條命令的,若是使用一下咱們就能看到系統的提示:No changes detected
(數據沒有更改)
admin.site.register 接受一個ModelAdmin子類做爲可選參數。用於控制模型類的顯示方式。
自定義admin列表步驟> [admin.py:] - ModelAdmin是admin的子類
class AuthorAdmin(admin.ModelAdmin):
#例如: list_display=('name','email','country') (包含字段名稱的元組)
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(統一資源定位符)全稱是UniformResourceLocator,是互聯網上用來標識某一處資源的地址。
包含了用於查找某個資源的足夠的信息。 URL分爲七個部分:
(詳解URL組成原文:http://blog.csdn.net/ergouge/1article/details/8185219 )
1.協議 2.域名 3.端口 4.虛擬目錄 5.文件名 6.錨 7.參數
assert False 來觸發出錯頁。 而後,你就能夠看到局部變量和程序語句了。
(__name__
:意爲當前目錄。)
BSD開源協議是一個給於使用者很大自由的協議。能夠自由的使用,修改源代碼,也能夠將修改後的代碼做爲開源或者專有軟件再發布。當你發佈使用了BSD協議的代碼,或者以BSD協議代碼爲基礎作二次開發本身的產品時,須要知足三個條件:
若是再發布的產品中包含源代碼,則在源代碼中必須帶有原來代碼中的BSD協議。
若是再發布的只是二進制類庫/軟件,則須要在類庫/軟件的文檔和版權聲明中包含原來代碼中的BSD協議。
不能夠用開源代碼的做者/機構名字和原來產品的名字作市場推廣。
BSD代碼鼓勵代碼共享,但須要尊重代碼做者的著做權。BSD因爲容許使用者修改和從新發布代碼,也容許使用或在BSD代碼上開發商業軟件發佈和銷 售,所以是對商業集成很友好的協議。
不少的公司企業在選用開源產品的時候都首選BSD協議,由於能夠徹底控制這些第三方的代碼,在必要的時候能夠修改或者 二次開發。
通用視圖
切勿退出裝飾器
│命名空間
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);
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)
在這裏安裝過的應用,本質其實都是對Python包的引入。咱們均可以在目錄中找到這些應用的位置。
看一下,就是這個socail_dango也是能夠找到的。(它是第三方包)
這裏的social_core
並無在應用中安裝。
今天我誤把AUTHENTICATION_BACKENDS看成了中間件,直到它報了不少錯誤。我才發現個人
social_core.backends.weibo.Weibo
不該該放在MIDDLEWARE
配置列表中。可是我學習了不少中間件的知識:
其實配置中間件的本質也就是經過訪問文件夾路徑來引入Python包中的一個個中間件,也就是類。(它們就是用於提供各類各樣的特殊的功能)。
pip install celery
pip install eventlet
task.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())
使用命令調用該文件,將其添加到任務隊列。
enventlet 就是剛纔咱們安裝的windows協程包。
將它交給運行器(worker)來等待處理。
Celery -A ./celery/task worker -l info -P eventlet
成功的運行結果
當celery被咱們開啓以後,它會一直等待消息命令的傳入,也就是說,這是能夠屢次觸發,屢次運行的。
from celery_tasks.tasks import send_sms_code send_sms_code.delay(mobile, sms_code) # 使用celery異步任務發送短信
在電商中對於商品,有兩個重要的概念:SPU和SKU
先看一段很是長的介紹
SPU是商品信息聚合的最⼩小單位,是⼀一組可服⽤用、易易檢索的標
準化信息的集合,該集合描述了了⼀一個產品的特性。
通俗的講,屬性值、特性相同的商品就能夠稱爲⼀一個SPU。
例例如:
iPhone X 就是⼀一個SPU,與商家、顏⾊色、款式、規格、套餐等
都⽆無關。
SKU即庫存進出計量量的單位,能夠是以件、盒、托盤等爲單位,
是物理理上不不可分割的最⼩小存貨單元。在使⽤用時要根據不不同業態,
不不同管理理模式來處理理。在服裝、鞋類商品中使⽤用最多最廣泛。
例例如:
iPhone X 全⽹網通⿊黑⾊色256G 就是⼀一個SKU,表示了了具體的規
格、顏⾊色等信息。
相信你們看完了剛纔的介紹,確定仍是蒙的,你說的這是啥?
不要緊,不用看剛纔那兩段話也能明白這兩個概念。
還有兩個圖供你們選擇:第一個圖適合未成年人觀看。
第二個圖也適合未成年人觀看。我本身畫的,醜可是很容易懂。
連接:點擊這裏就不會錯過青魔法聖堂法術 DRF (Django REST framework) 框架(持續更新)
連接:更多請關注個人青魔法Python