1. 程式人生 > >Django 從入門到放棄(筆記)

Django 從入門到放棄(筆記)

django 1.10.1 pycharm 前端 http/css/jq 後端 python或者其他

所以要在要引用static中的檔案中 加{% name “檔案路徑” %}

django 專案至少包含一個以上的應用 novel 增加的app/應用 webapp 專案 manage.py 管理檔案 開發流程: 1.建立虛擬環境 2.安裝django 3.建立專案 4.建立應用 5.在models.py中定義模型 6.定義檢視 7.配置url 8.建立模板

MVC(解耦) 的 功能:低耦合 高內聚 高可擴充套件性 m(model) 表示資料庫層的封裝 v(view) 用於向用戶展示結果 c(controller) 核心 處理請求 獲取資料 返回結果 基於MVC的MVT框架 M(model) 負責與資料庫的互動 V(view) 核心 處理請求獲取資料 返回結果 T(template) 負責呈現內容發到瀏覽器

首先安裝虛擬環境 首先 電腦上面有python

安裝 virtualenv虛擬環境
	pip install virtualenv
使用虛擬環境建立目錄
	virtualenv venv
這是一個單獨的虛擬環境  然後 用
	venv\Scripts\activate
	進入 命令前面帶《vnev》	的 虛擬環境
	
	如果是linux 則用
	source venv/bin/activate
	進入 命令前面帶《vnev》	的 虛擬環境
	deactivate  退出虛擬環境


pip install django  在虛擬環境裡面安裝 django

django-admin startproject name			建立專案 
tree . 			檢視結構

Django目錄說明

manage.py:一個命令列工具,可以使你用多種方式對Django專案進行互動(應該是和資料庫進行互動)

	內層的目錄:專案的真正的Python包

	_init _.py:一個空檔案,它告訴Python這個目錄應該被看做一個Python包
	settings.py:專案的配置
	urls.py:專案的URL宣告
	wsgi.py:專案與WSGI相容的Web伺服器入口
app_name 
	__init__.py
	migrations       用於資料遷移
		__init__.py
	admin.py 		 django自動生成的後臺管理頁面,無須在此作修改
	apps.py 		 當前app的配置檔案
	models.py 		 資料模型,和其他語言的一樣
	views.py 		 定義前臺顯示的介面	引入前臺網頁檔案
	tests.py 		 用於做測試的
	urls.py			 在settings中urls 的include()引入 這個  然後通過這個路由顯示前臺頁面
templates		  模板資料夾	需要在setting中TEMPLATES 設定 DIRS :[os.path.join(BASE_DIR,'templates')]
	app_name
		index.html	前臺顯示網頁檔案

原理:傳送一個http請求 到settings中url中找 然後跳轉到app url中找 有路由對應的頁面 然後顯示

如果是手動建立的 注意在setting中app中加入 不然後來呼叫的時候呼叫不到模板檔案

建立的app中有兩個資料夾 其中一個是 templates 存放模板檔案的資料夾 (將前端檔案開發的問價能放進去) 然後在檢視函式中 用render呼叫就可以了

三個引數render(request,模板中的主頁檔名)

在django中是不能直接訪問靜態檔案的 必須通過app中的static資料夾中才能訪問

生成資料表 啟用模型 在settings中 將booktest應用加入到installed_apps中

生成遷移檔案:根據模型類生成sql語句 python manage.py makemigrations 執行遷移:執行sql語句生成資料表 python manage.py migrate

進入終端環境測試 python manage.py shell 例項化物件對資料庫進行增刪改查 from apptest import * from datetime import * #新增資料 b = Bookinfo b.btitle =‘abc’ b.save() 提交 b.delete() 刪除 Bookinfo.objects.all() 檢視 b = Heroinfo.objects.get(pk=1) b.heroinfo_set() 取出heroinfo這個對應的所有制

**

專案開始

模型 查詢 類.成員.查詢方法(屬性名稱_ _比較運算子=值) 例如 BookInfo.creat.filter(btitle__contains='傳') 查詢btitle這個欄位區分大小寫的帶傳的值 定義模型 在app 裡面的models.py 裡面寫模型 類似於 `from django.db import models class Book(models.Model): #成員 title = models.CharField(max_length=100) CharField 定義好的欄位 max_length 值的長短 class Meta(): 模板裡面有元選項 Meta 管理器 作用:更改查詢級,增加建立物件的方法 是模型類的屬性 用於將物件與資料表對映 還有好多方法 稱之為 過濾器 查詢方法 get拿一個 filter拿多個

			all()
			filter()
			order_by()
			values()	一個物件構成一個字典 然後構成一個列表返回
		返回單個值的方法
			get():返回單個滿足條件的物件
				如果未找到會引發"模型類.DoesNotExist"異常
				如果多條被返回,會引發"模型類.MultipleObjectsReturned"異常
			count():返回當前查詢的總條數
			first():返回第一個物件
			last():返回最後一個物件
			exists():判斷查詢集中是否有資料,如果有則返回True
		
		**快取的問題** 		拿到的資料會快取 下次再拿就從快取裡面拿資料
		
		objects管理器 是manage類的物件 用於和資料庫的互動
		
		當每次需要去賦值的時候麻煩 在類裡面寫init方法 但是不能寫 所以自己寫一個方法
		@classmethd
		def name(cls,btitle。。。)
			b= BookInfo()
			b.btitle=btitle
			...
			return b
		還可以在管理器裡面寫 然後通過管理器呼叫
		
		
		#可以根據model檔案生成sql語句去建立表	  
		
	查詢的問題 
	
		限制查詢集
		
		查詢集的快取
		
		欄位查詢
		
		聚合函式	使用aggregate()函式返回聚合函式的值	函式:Avg,Count,Max,Min,Sum
		
		F物件	欄位A與欄位B進行比較	例	list.filter(bread__gte=F('bcommet'))
		
		Q物件	需要進行or查詢,使用Q()物件		Q物件可以使用&(and)、|(or)操作符組合起來
				例  list.filter(Q(pk_ _lt=6) | Q(bcommet_ _gt=10))
	
		
		外來鍵的問題 另一張表裡面會生成一個   book_id的列 可以通過這個查``

後臺管理

	編輯settings.py檔案,設定編碼、時區
		LANGUAGE_CODE = 'zh-Hans'
		TIME_ZONE = 'Asia/Shanghai'
	建立一個管理員使用者
		python manage.py createsuperuser,按提示輸入使用者名稱、郵箱、密碼
	啟動之後開啟127.0.0.1:8000/admin   登入就能看到頁面了
	
	
	
	向admin註冊booktest的模型
		開啟booktest/admin.py檔案,註冊模型
		from django.contrib import admin
		from models import BookInfo
		admin.site.register(BookInfo)

	ModelAdmin物件
		ModelAdmin類是模型在Admin介面中的表示形式
		定義:定義一個類,繼承於admin.ModelAdmin,註冊模型時使用這個類
		class HeroAdmin(admin.ModelAdmin):
		
		使用方式一:註冊引數
		admin.site.register(HeroInfo,HeroAdmin)
		使用方式二:註冊裝飾器
		@admin.register(HeroInfo)
		class HeroAdmin(admin.ModelAdmin):
		
	
	

	admin 中新增關聯

檢視檔案 就是前臺的檔案 (進來一個url請求 去掉域名和埠進行匹配 成功返回頁面 不成功返回404)

	一個url()物件包括:
	正則表示式
	檢視函式	
	名稱name

	想獲得url中的引數 用括號括起來 然後在檢視中接受 
	
	正則表示式命名組,通過關鍵字引數傳遞給檢視,本例中關鍵字引數為id  ?<id>
	url(r'(?<id>\d+)')
	
	可以給url取名字   name  如果有include 增用namespace    用於反向解析
	
錯誤模板
	
	404  在template下面寫404.html 
		settings.py中修改除錯
			DEBUG = False
			ALLOWED_HOSTS = ['*', ]
	
	505	在檢視程式碼中出現執行時錯誤
	
	400 錯誤來自客戶端的操作
	

request 物件 
		
		
	path:一個字串,表示請求的頁面的完整路徑,不包含域名
	method:一個字串,表示請求使用的HTTP方法,常用值包括:'GET'、'POST'
	encoding:一個字串,表示提交的資料的編碼方式
	如果為None則表示使用瀏覽器的預設設定,一般為utf-8
	這個屬性是可寫的,可以通過修改它來修改訪問表單資料使用的編碼,接下來對屬性的任何訪問將使用新的encoding值
	GET:一個類似於字典的物件,包含get請求方式的所有引數
	POST:一個類似於字典的物件,包含post請求方式的所有引數
	FILES:一個類似於字典的物件,包含所有的上傳檔案
	COOKIES:一個標準的Python字典,包含所有的cookie,鍵和值都為字串
	session:一個既可讀又可寫的類似於字典的物件,表示當前的會話,只有當Django 啟用會話的支援時才可用,詳細內容見“狀態保持”
	
	
	QueryDict物件 類似以字典 可以重複的字典
	
	get 傳參 在url地址中傳參 
		配置url 	url(r'^getTest1/$', views.getTest1),
		定義檢視檔案中對應的檢視 是對應的模板檔案
		
		一對一
		用  request.GET['']   來取值
		
		一對多
		   a=request.GET.getlist('a')
		
		
	
	post 在表單中傳參
		method='post' action='apptest/posttest1'		action 表示提交到哪裡 和url保持一致
	
		根據提交的 name:value   就是name 對應的值
		通過request.POST['name']   或者request.POST.get('name')   request.POST.getlist('name')
	
	
	
response 瀏覽器給客戶端的返回資訊
	
	cookie : 儲存在瀏覽器中的一段文字資訊  以鍵值對的方式儲存
	set_cookie(key, value='', max_age=None, expires=None):設定Cookie max_age是過期時間
	可以在response中設定 返回給客戶端儲存  例如
		response = HttpResponse()
		response.set_cookie('t1','abc')
	獲取cookie
		cookie = request.COOKIES
			if cookie.has_key('t1')
				response.write(cookie['ti'])
	
	基於HttpRsponse的子類
		
		HttpResponseRedirect		重定向
		return HttpResponseRedirect('js/')
		
		JsonResponse		json非同步請求
		return JsonResponse({'list': 'abc'})
		
	狀態保持 
		瀏覽器是無狀態的 不知道你之前做過什麼  所以要用cookie 或者session來記錄你之前做過的事情
		cookie  存在瀏覽器端的   
		
		
		session  存在伺服器端的 
			啟用會話後,每個HttpRequest物件將具有一個session屬性,它是一個類字典物件
			get(key, default=None):根據鍵獲取會話的值
			clear():清除所有會話
			flush():刪除當前的會話資料並刪除會話的Cookie
			del request.session['member_id']:刪除會話
			會話過期時間
				set_expiry(value):設定會話的超時時間
				如果沒有指定,則兩個星期後過期
				如果value是一個整數,會話將在values秒沒有活動後過期
				若果value是一個imedelta物件,會話將在當前時間加上這個指定的日期/時間過期
				如果value為0,那麼使用者會話的Cookie將在使用者的瀏覽器關閉時過期
				如果value為None,那麼會話永不過期
			session 是存在資料庫中的 記憶體中和快取中的  
			在settings裡面可以設定 儲存在哪裡的 
				例如可以儲存在redis中
					SESSION_ENGINE = 'redis_sessions.session'
					SESSION_REDIS_HOST = 'localhost'
					SESSION_REDIS_PORT = 6379
					SESSION_REDIS_DB = 0
					SESSION_REDIS_PASSWORD = ''
					SESSION_REDIS_PREFIX = 'session'
			session依賴於cookie    伺服器上通過cookie來區別不同的session 

模板

包含 html 靜態 
		動態插入部分
		可以放在根目錄下面 也能放在專案的目錄下面
		django模板語言			DTL(Django templates language) 
			變數{{ name }}   
			標籤 { % 程式碼塊 % }
			過濾器
			註釋{# 程式碼或html #}
		for	
			{ %for ... in ...%}
			迴圈邏輯
			{{forloop.counter}}表示當前是第幾次迴圈
			{ %empty%}
			給出的列表為或列表不存在時,執行此處
			{ %endfor%}
		if
			{ %if ...%}
			邏輯1
			{ %elif ...%}
			邏輯2
			{ %else%}
			邏輯3
			{ %endif%}
		comment	
			{ % comment % }
			多行註釋
			{ % endcomment % }
		include:載入模板並以標籤內的引數渲染
			{ %include "foo/bar.html" % }
		url:反向解析
			{ % url 'name' p1 p2 %}
		csrf_token:這個標籤用於跨站請求偽造保護
			{ % csrf_token %}
		布林標籤:and、or,and比or的優先順序高
	過濾器
		語法:{ { 變數|過濾器 }},例如{ { name|lower }},表示將變數name的值變為小寫輸出
		使用管道符號 (|)來應用過濾器
		通過使用過濾器來改變變數的計算結果
		可以在if標籤中使用過濾器結合運算子
		反向解析{ % url 'name' p1 p2 %}   在html中action=‘ ’    
			‘name’   寫 ‘namespace:name’
				namespace 是第一層url中的   第二個name 是檢視中的名字 
				p1 p2 是傳過來的值   url(r'(\d+)/(\d+)',vires.index,name=name)
				可以根據html中的反向解析來找對應的url
	

模板繼承

block標籤:在父模板中預留區域,在子模板中填充
		extends繼承:繼承,寫在模板檔案的第一行
		
		在一個base.html中寫html檔案 在需要挖坑的地方寫{%block name %}	{% endblock name%}
		在需要繼承的模板中 {% extends 'base.html'%}   {%block name%} 	{% endblock name%}
			ps:是不是可以理解為替換
		
		html轉義    Django對字串進行自動HTML轉義  檢視中傳到模板中的自動轉義
			< 會轉換為&lt;
			> 會轉換為&gt;
			' (單引號) 會轉換為&#39;
			" (雙引號)會轉換為 &quot;
			& 會轉換為 &amp;
			關閉的話	{{ data|safe }}   用safe 過濾就行了
				或者{ % autoescape off %}
					{{ body }}
					{ % endautoescape %}
		csrf 跨站請求偽造  可以不再你的網站向你的網站發起請求也成功	
			在發起表單post的時候 加 {% csrf_token %} 就行了
			或者加驗證碼也能防禦
	驗證碼問題		表單的image的src指向這個函式就行了 例如 <img src=''>
			首先在伺服器上面建立驗證碼圖片用 	from io import BytesIO  在記憶體中做操作 
			request.session['code'] = 字元     用來做驗證的 
			然後 HttpResponse(buf,'image/png')			返回一個圖片
			思路就是 重新整理就請求圖片檢視在圖片檢視中把值給session 然後使用者輸入提交到
				驗證檢視 然後通過session中的值和post提交過來的值作比較
			
			
		from django.http import HttpResponse
		def index(request):
			return HttpResponse(‘hello’)
			
	引入模板檔案		
		def index(request):
			
			list = BookInfo.objects.all()
			context={‘list’:'list1'}
			return render(request,'apptest/index.html',context)
			render 就是渲染 填坑
	主專案裡面的urls import include   然後url(r'^',include('apptest.urls'))
		在apptest urls中定義路由
		
	建立template/apptest/index.html  然後在setting中TEMPLATES 設定 DIRS :[os.path.join(BASE_DIR,'templates')]

高階

靜態檔案			不在服務端進行處理的  直接拿過去就給瀏覽器了 所以會有邏輯路徑
		manage同級建立一個static 						
		setting 中設定
		#這是邏輯上顯示的路徑
		STATIC_URL = '/static/'  			
		#物理上存在的路徑
		STATICFILES_DIRS 中設定os.path.join(BASE_DIR, 'static')		
		如果在網頁檔案中需要用到靜態檔案的時候  要在上面引入
		
		例如頁面中要用
		 { % load static from staticfiles %}
	 	<img src="{ % static "my_app/myexample.jpg" %}" alt="My image"/>
		這是從setting中找STATICFILES_DIRS 路徑裡面的東西
		
		
	

中間鍵 面向切面程式設計	 		通俗理解 你可以用中間鍵干預django專案的執行 而不用改原始碼
		在setting中有MIDDLEWARE_CLASSES 可以一個類 是在專案中自己定義的檔案中的類
		這個類中寫方法  就會被呼叫 方法名必須和下面一樣
			_init _:無需任何引數,伺服器響應第一個請求的時候呼叫一次,用於確定是否啟用當前中介軟體
			process_request(request):執行檢視之前被呼叫,在每個請求上呼叫,返回None或HttpResponse物件
			process_view(request, view_func, view_args, view_kwargs):呼叫檢視之前被呼叫,在每個請求上呼叫,返回None或HttpResponse物件
			process_template_response(request, response):在檢視剛好執行完畢之後被呼叫,在每個請求上呼叫,返回實現了render方法的響應物件
			process_response(request, response):所有響應返回瀏覽器之前被呼叫,在每個請求上呼叫,返回HttpResponse物件
			process_exception(request,response,exception):當檢視丟擲異常時呼叫,在每個請求上呼叫,返回一個HttpResponse物件

例如在 apptest新建expo.py 裡面有一個類expo2 在setting中MIDDLEWARE_CLASSES 寫 apptest.expo.expo2 然後執行的時候就會 在哪一步去找對應的方法

上傳圖片 圖片儲存路徑 在專案根目錄下建立media資料夾 圖片上傳後,會被儲存到“/static/media/cars/圖片檔案” 開啟settings.py檔案,增加media_root項 MEDIA_ROOT=os.path.join(BASE_DIR,“static/media”)

	當Django在處理檔案上傳的時候,檔案資料被儲存在request.FILES
	FILES中的每個鍵為<input type="file" name="" />中的name
	注意:FILES只有在請求的方法為POST 且提交的<form>帶有
		enctype="multipart/form-data" 的情況下才會包含資料。否則,FILES 將為一個空的類似於字典的物件
	使用模型處理上傳檔案:將屬性定義成models.ImageField型別
	上傳檔案html	
			<form method="post" action="upload/" enctype="multipart/form-data">
				<input type="text" name="title"><br>
				<input type="file" name="pic"/><br>
				<input type="submit" value="上傳">
			</form>
	處理檢視程式碼
	if request.method == "POST":
		f1 = request.FILES['pic']							請求中的檔案給f1
		fname = '%s/cars/%s' % (settings.MEDIA_ROOT,f1.name)	伺服器檔案路徑拼接
		with open(fname, 'w') as pic:
			for c in f1.chunks():
				pic.write(c)							儲存檔案
		return HttpResponse("ok")
	else:
		return HttpResponse("error")
	
	
	pic=models.ImageField(upload_to='cars/')

分頁


		Paginator物件			from django.core.paginator import *
		Paginator(列表,int):返回分頁物件,引數為列表資料,每面資料的條數
		屬性
			count:物件總數
			num_pages:頁面總數
			page_range:頁碼列表,從1開始,例如[1, 2, 3, 4]
		
		方法
			page(num):下標以1開始,如果提供的頁碼不存在,丟擲InvalidPage異常
					Paginator物件的page()方法返回Page物件,不需要手動構造
				屬性
				object_list:當前頁上所有物件的列表
				number:當前頁的序號,從1開始
				paginator:當前page物件相關的Paginator物件
				方法
					has_next():如果有下一頁返回True
					has_previous():如果有上一頁返回True
					has_other_pages():如果有上一頁或下一頁返回True
					next_page_number():返回下一頁的頁碼,如果下一頁不存在,丟擲InvalidPage異常
					previous_page_number():返回上一頁的頁碼,如果上一頁不存在,丟擲InvalidPage異常
					len():返回當前頁面物件的個數
					迭代頁面物件:訪問當前頁面中的每個物件
										例如找 page對應Paginator的屬性用paginator
				例如 list1 =Paginator(list,int)
					然後在html中呼叫方法

	
			

自連線

 就是表 裡面外來鍵之類的 然後通過主表訪問其他或者通過其他訪問主表
				上級物件:area.aParent						a:b   1:n					b.a
				下級物件:area.areainfo_set.all() 			a.b_Set
				示例  這是一級
				insert into 'apptest_areainfo2' values ('110100','北京市',null);
				這是二級
				insert into 'apptest_areainfo2' values ('11001','北京市','110100');
				這是三級
				insert into 'apptest_areainfo2' values ('11100','北京市','11001');
		

ajax(沒成功)

 目前理解來說就是 通過jQuery  向另一個檢視獲取資料然後展示  是通過jQuery script 來實現的
			首先建立一個首頁檢視  然後再建立一個檢視 讓第一個檢視中的script &get 向這裡發請求
					第二個檢視返回的是一個json資料 然後頁面中的jQuery處理輸出
					用jQuery的   $.get('url',caloback函式)   來獲取這個檢視的資料
				

		快取 
			通過設定決定把資料快取在哪裡,是資料庫中、檔案系統還是在記憶體中
			通過setting檔案的CACHES配置來實現
			引數TIMEOUT:快取的預設過期時間,以秒為單位,這個引數預設是300秒,即5分鐘;
				 設定TIMEOUT為None表示永遠不會過期,值設定成0造成快取立即失效

第三方



		富文字編輯器()
		1.可以在admin後臺顯示
		2.可以在網頁中顯示 (要加js程式碼 引入 然後呼叫)
		
		
	全文檢索:
		haystack:django的一個包,可以方便地對model裡面的內容進行索引、搜尋,設計為支援whoosh,solr,Xapian,Elasticsearc四種全文檢索引擎後端,屬於一種全文檢索的框架
		whoosh:純python編寫的全文搜尋引擎 
		jieba:中文分詞庫
		
	
	
	celery		當瀏覽器中傳送一個耗時的操作  可以用這個來瞬間返回response 而費時的操作給celery來做
		示例一的解決:將耗時的程式放到celery中執行
		示例二的解決:使用celery定時執行
		名詞
			任務task:就是一個Python函式
			佇列queue:將需要執行的任務加入到佇列中
			工人worker:在一個新程序中,負責執行佇列中的任務
			代理人broker:負責排程,在佈置環境中使用redis

ps:網頁中寫的東西向資料庫中寫 用post 傳到一個檢視中 然後 例如 test= Heroinfo.object.get(pk=1) test.hero=request.POST[‘name’] test.save()