Python——Django学习笔记
Django——一個(gè)封裝好的神奇框架
若本文有任何內(nèi)容錯(cuò)誤,望各位大佬指出批評(píng),并請直接聯(lián)系作者修改,謝謝!小白學(xué)習(xí)不易。
一、簡要模型
模型類操作數(shù)據(jù)表:
python manage.py shell制作遷移文件:
python manage.py makemigrations執(zhí)行遷移文件:
python manage.py migrate from booktest.models import BookInfo實(shí)例化對象,設(shè)置對象實(shí)例屬性值,調(diào)用對象.save()方法
查詢:
b = BookInfo.objects.get #要查詢的條件,如id=1b是根據(jù)條件查詢到的內(nèi)容,類型為BookInfo對象
實(shí)體類之間的主外鍵:主類:
hbook = models.ForeignKey('BookInfo') h2.hbook = b #h2為實(shí)例化對象,b為bookInfo的實(shí)例化對象,主外鍵對應(yīng)b.heroinfo_set.all()查詢與外鍵相關(guān)聯(lián)的主鍵集合
1、models模型類:
class AreaInfo(models.Model):atitle = models.CharField(verbose_name='地區(qū)',max_length=20) # verbose_name指定屬性列列名稱def title(self):return self.atitletitle.admin_order_field = 'atitle' #指定該列點(diǎn)擊列標(biāo)題根據(jù)atitle進(jìn)行排序 title.short_description = '地區(qū)名稱' #指定該列列標(biāo)題為地區(qū)名稱重寫str方法可讓管理頁面顯示正確的中文內(nèi)容
在admin中注冊實(shí)體類信息,管理員可進(jìn)行后臺(tái)管理,實(shí)行數(shù)據(jù)的CRUD,此外,在admin中建立自定義模型管理類class,繼承admin.ModelAdmin可以設(shè)置頁面顯示內(nèi)容:
class AreaInfoAdmin(admin.ModelAdmin):list_display = ['id','btitle','bpub_date'] #頁面數(shù)據(jù)顯示格式 list_per_page=['10'] #可以設(shè)置每頁顯示數(shù)據(jù)條數(shù), list_filter=['atitle'] #列表右側(cè)過濾欄,一標(biāo)題進(jìn)行過濾,可進(jìn)行快速查找 actions_on_bottom = True # 操作欄顯示在下面 search_fields=['atitle'] #列表頁上方的搜索框,以標(biāo)題進(jìn)行搜索 fields=['字段1','字段2'] #指定編輯頁的上下順序 admin.site.register(AreaInfo, AreaInfoAdmin)2、關(guān)聯(lián)對象:
一對多的關(guān)系中,在一端的編輯頁面中編輯多端的對象,可嵌入表格或塊兩種,InlineModelAdmin:在編輯頁面嵌入關(guān)聯(lián)的模型;TabularInline:以表格形式嵌入;StackedInline:以塊形式嵌入:
booktest/admin.py:
class AreaStackedInline(admin.StatickedInline):model = AreaInfo # 關(guān)聯(lián)子對象 extra = 2 # 增加兩個(gè)額外的子對象?
在booktest/admin.py中,AreaAdmin類:
class AreaAdmin(admin.ModelAdmin):......inlines = [AreaStackedInline]二、簡要視圖與模板
from django.http import HttpResponse函數(shù),參數(shù)為request,返回 HttpResponse()
在新建urls里配置url,
from django.conf.urls import urlfrom booktest import viewsurl(r'^index$',views.index) #建立index和視圖index之間的關(guān)系,嚴(yán)格匹配開頭和結(jié)尾在系統(tǒng)urls中添加配置項(xiàng)
url(r'^', include('booktest.urls')) # 包含booktest應(yīng)用中的應(yīng)用文件settings里TRMPLATES的DIRS設(shè)置模板路徑:
'DIRS':[os.path.join(BASE_DIR,,'templates')]2.1、數(shù)據(jù)庫配置:
DATABASES:'NAME':'數(shù)據(jù)庫名','USER':'用戶名','PASSWORD':'密碼','HOST':'IP','PORT':3306,__init__.py里:
import pymysqlpymysql.install_as_MySQLdb()2.2、示例過程
在views里寫index方法:
from django.template import loaderdef index(request):temp = loader.get_template('booktest/index.html') # 加載模板文件 context = RequestContext(request,{ }) # 定義模板上下文,給模板傳數(shù)據(jù) res_html = temp.render(context) # 模板渲染:產(chǎn)生標(biāo)準(zhǔn)的HTML內(nèi)容return HttpResponse(res_html) # 返回給瀏覽器簡化方法一:*******將此函數(shù)封裝成固定函數(shù)
def my_render(request,template_path,context_dict):temp = loader.get_template(template_path) # 加載模板文件 context = RequestCOntext(request,context_dict) # 定義模板上下文,給模板傳數(shù)據(jù) res_html = temp.render(context) # 模板渲染:產(chǎn)生標(biāo)準(zhǔn)的HTML內(nèi)容return HttpResponse(res_html) # 返回給瀏覽器簡化方法二:*******直接調(diào)用系統(tǒng)方法
return render(request,'booktest/index.html',{'grent':'hello django!'})HTML頁面用{{ content }}顯示傳輸?shù)臄?shù)據(jù)
傳輸列表:
render(request,'booktest/index.html',{'list':list(range(1,10))})HTML頁面用{{ list }}直接顯示內(nèi)容
遍歷:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
{% for i in list %}<li>{{ i }}</li>{% empty %} 若值問空,則調(diào)用此方法<li>沒有值</li>{% endfor %}可以通過{{ forloop.counter }}的到遍歷到了第幾次{% if 條件 %}{% elif 條件 %}{% else %}{% endif %}?????????????????????????????????? 關(guān)系比較符:> < >= <= == !=(進(jìn)行比較操作時(shí),操作符兩邊必須有空格!)
?????????????????????????????????? 邏輯運(yùn)算:not and or
鏈接傳值時(shí)的urls設(shè)置
url(r'^books/(\d+)$' , views.detail)? ? (\d+需要加括號(hào)),分組。
三、模型
3.1、mysql查詢:
get 返回的事查詢到的對象,其余返回的是查詢集的對象
等值查詢:
BookInfo.objects.get(id=1) == BookInfo.objects.get(id__exact=1)模糊查詢:? **所有下劃線均為雙下劃線**
BookInfo.objects.filter(btitle__contains='傳') #包含 BookInfo.objects.filter(btitle__endswith='部') #以關(guān)鍵字結(jié)尾空查詢:
BookInfo.objects.filter(btitle__isnull=False) #不為空范圍查詢:
BookInfo.objects.filter(id__in=[1,3,5]) #查詢id為1或3或5的書籍比較查詢:gt(greatr than)、lt(less than) gte(equals) lte(<=)
BookInfo.objects.filter(id__gt=3) #查詢編號(hào)大于3的圖書日期查詢:
BookInfo.objects.filter(bpub_date__year=1990) #查詢?nèi)掌跒?990年發(fā)表的圖書 BookInfo.objects.filter(bpub_date__gt=date(1990,1,1)) #查詢1990年1月1日后發(fā)表的書3.2、exclude方法與排序:
BookInfo.objects.exclude(id=3) #查詢id不為3的書籍order_by:
BookInfo.objects.all().order_by('id') #根據(jù)id從小到大排序 BookInfo.objects.all().order_by('-id') #從大到小3.3、Q對象:
from django.db import Q或:
BookInfo.objects.filter(Q(id__gt=3)|Q(bread__gt=30))且:
BookInfo.objects.filter(id__gt=3,bread__gt=30) == BookInfo.objects.filter(Q(id__gt=3)&Q(bread__gt=30))非:
BookInfo.objects.filter(~Q(id=3))3.4、F對象:
(類屬性之間的比較)
from django.db import FBookInfo.objects.filter(bread__gt = F('bcomment')) #查詢圖書閱讀量大于2倍評(píng)論量圖書信息3.5聚合函數(shù):
aggregate進(jìn)行聚合操作,返回值是一個(gè)字典
?
sum count avg max min
from django.db.models import Sum,Count,Max,Min,AvgBookInfo.objects.all().aggregate(Count('id')) #返回字典 BookInfo.objects.all().count() #返回?cái)?shù)值3.6、查詢集特性:
?????? 只有在真正使用查詢集中的數(shù)據(jù)的時(shí)候才會(huì)真正發(fā)生對數(shù)據(jù)庫的真正查詢;
?????? 當(dāng)使用的是同一個(gè)查詢集時(shí),第一次的查詢會(huì)將結(jié)果緩存,之后使用的是緩存中的結(jié)果;
?????? 可對查詢集進(jìn)行切片,但是下標(biāo)不能為負(fù)數(shù);
3.7模型類關(guān)系:
一對多:models.ForeignKey() ——必須定義在多的類中
多對多:models.ManyToManyField()
一對一:models.OneToOneField()
3.8、模型關(guān)聯(lián)查詢:
id為1的圖書關(guān)聯(lián)英雄信息:
b = BookInfo.objects.get(id=1) b.heroinfo_set.all()BoojInfo圖書類? ——? 一類?????????? HeroInfo英雄人物類? ——? 多類
b.heroinfo_set.all()??? ——? 一查多
h.hbook? ——? 多查一
3.9、管理器:
objects為models。Manager類對象,每個(gè)類都有
一般自定義模型管理類,繼承自models.Manager,可自定義函數(shù)改變查詢的結(jié)果集
類中使用self.model()可以創(chuàng)建跟自定義管理器對應(yīng)的模型類對象。
?
圖一:管理器流程圖
3.10、元選項(xiàng):
在項(xiàng)目中遇到中途需要修改項(xiàng)目名等情況時(shí),可以指定元類,讓模型表名不依賴于對應(yīng)的表名:
class Meta:db_table = 'bookinfo'?
四、視圖
視圖函數(shù):
request參數(shù)必須有,參數(shù)名可以變化,是一個(gè)HttpRequest類型的對象。
4.1、錯(cuò)誤頁面
找不到頁面,關(guān)閉settings里的調(diào)試模式后,默認(rèn)會(huì)顯示一個(gè)標(biāo)準(zhǔn)的錯(cuò)誤頁面,自定義錯(cuò)誤頁面,需要在templates目錄下自定義一個(gè)404.html文件。
錯(cuò)誤:404——url沒有配置/url配置錯(cuò)誤
????????????? ? 500——視圖出錯(cuò)
網(wǎng)站開發(fā)完成需要關(guān)閉調(diào)試模式:
DEBUG = FalseALLOWED_HOST = [ '*' ]4.2、捕獲url參數(shù):
將所要捕獲的部分設(shè)置成正則表達(dá)式組,django會(huì)自動(dòng)將匹配成功的相應(yīng)組內(nèi)容作為參數(shù)傳遞給視圖參數(shù)。
4.3、請求方法
頁面表單的POST和GET:
POST——數(shù)據(jù)在請求頭中,多出現(xiàn)在表單
GET——數(shù)據(jù)在url中,不安全,多出現(xiàn)在超鏈接
后臺(tái)通過request去獲取數(shù)據(jù),是一個(gè)QueryDict對象,里面的鍵可重復(fù),取到的是后面的值,用getlist('鍵')可取到某名的所有值,用類字典方式提取,最好用get方法,不存在不會(huì)報(bào)錯(cuò)。
4.4、Ajax
重要兩點(diǎn):訪問地址時(shí)需要攜帶的參數(shù);試圖處理完成后返回的json格式。
應(yīng)用文件下創(chuàng)建static文件夾,在settings里配置
STATIC_URL = '/static/' #HTML頁面訪問靜態(tài)文件對應(yīng)的url地址 STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]需要先導(dǎo)入jquery文件,并在HTML文件里引用,隨后:
<script>$(function(){$('#btnAjax').click(function(){alert(1)$.ajax({'url':請求地址,'type':請求方式,'dataType':預(yù)期返回的數(shù)據(jù)格式,'data':參數(shù)}).success(function(data){//執(zhí)行成功后的回調(diào)函數(shù)alert(2)if(data.res == 1){$('#message').show().html('自定義提示信息!')}})alert(3)})})</script><input tybe='button' id='btnAjax' value='ajax請求'/>?
Django返回: return JsonResponse({'res':1})
異步:alert順序1-3-2,也就是在按鈕事件后,會(huì)繼續(xù)執(zhí)行ajax中的代碼,而不會(huì)等服務(wù)器把結(jié)果發(fā)來之后再執(zhí)行回調(diào)函數(shù)success。
同步:在ajax請求里加上?? 'async':false, 就會(huì)是同步的ajax請求。
4.5、Cookie緩存:
添加cookie緩存需要HttpResponse對象的一個(gè)實(shí)例調(diào)用.set_cookie()方法,參數(shù)為鍵值對,取出cookie為request.COOKIES()參數(shù)為鍵名
4.6、session:
?
?
圖二:session流程圖
以鍵值對存儲(chǔ),依賴于cookie,默認(rèn)兩周過期。
設(shè)置:
request.session['username']='jery'取值:
request.session['username']4.7、比較:
cookie:記住用戶名,安全性要求不高,
session:安全性比較高,賬戶,密碼,余額等。
五、模板
兩部分:靜態(tài)內(nèi)容(css,js,html);動(dòng)態(tài)內(nèi)容(模板語言:編程語言)
5.1、模板文件的加載順序:
?????? 去配置的模板目錄下找模板文件;
?????? 去INSTALLED_APPS下每個(gè)應(yīng)用找模板文件,前提是應(yīng)用中必須有templates文件夾(templates——>admin——>auth)
模板語言(DTL Django Template Language):
?????? 模板變量:
?????? {{ book.btitle }}解析順序:
????????????? book當(dāng)成字典,btitle當(dāng)成鍵名,取值book['btitle'];
????????????? book當(dāng)成對象,btitle當(dāng)成屬性,取值book.btitle;
????????????? book當(dāng)成對象,btitle當(dāng)成對象的方法,取值book.btitle;
?????? {{ book.0 }}解析順序:
????????????? book當(dāng)成字典,0當(dāng)成鍵名,取值book['0']
????????????? book當(dāng)成列表,0當(dāng)成下標(biāo),取值book[ 0 ]
?????? 若解析失敗,產(chǎn)生內(nèi)容時(shí)Django框架會(huì)自動(dòng)用空字符串填充模板變量。
5.2、過濾器:
模板變量|過濾器:參數(shù)?
如:
{{ book.bpub_date|date:'Y年-m月-d日' }}{{ book.btitle|length }}{{ content|default:'為空' }}自定義過濾器:應(yīng)用下新建templatetags
新建自定義名filters.py文件:
from django.template import Libraryregister = Library()@register.filterdef mod(num):return num%2 == 0 #判斷num是否為偶數(shù)HTML引用過濾器:
{% load filters %}{% if book.id|mod %}5.3、模板注釋
(網(wǎng)頁源代碼不會(huì)顯示注釋的內(nèi)容):
?????? 單行注釋:{# 注釋內(nèi)容 #}
?????? 多行注釋:{% comment %}?? 注釋內(nèi)容??? {% endcomment %}
5.4、模板繼承:
父文件:
{% block 塊名 %} 中間內(nèi)容可為空 {% endblock 塊名 %}子文件:
{% extends 'booktest:/base.html' %}{% block 塊名 %} 覆蓋子模板內(nèi)容,也可調(diào)用父模板內(nèi)容{{ block.super }} {% endblock 塊名 %}
5.5、HTML轉(zhuǎn)義:
模板上下文中的html標(biāo)簽?zāi)J(rèn)會(huì)被轉(zhuǎn)義,關(guān)閉轉(zhuǎn)義可用:
?????? safe過濾器:{{ 模板變量|safe }}
?????? autoescape標(biāo)簽:{{% autoescape off %}}被取消轉(zhuǎn)義的內(nèi)容 {{% endautoescape %}}
5.6、csrf攻擊:
登錄裝飾器:
有些頁面是用戶登錄之后才能訪問的,訪問某些抵制需要先進(jìn)性登錄的判斷,即攔截器,此過程可定義為一個(gè)裝飾器:
def login_required(view_func):def wrapper(request, *view_args, **view_kwargs):if request.session.has_key('isLogin')return view_func(request, *view_args, **view_kwargs)else:return redirect('/login')return wrapperview函數(shù)前引用@login_required
?
在已經(jīng)登錄某網(wǎng)站后,其他網(wǎng)站或網(wǎng)頁利用緩存數(shù)據(jù)模擬向網(wǎng)站發(fā)出一些請求,即跨站請求。
?
圖三:csrf攻擊模式
方法:
?????? Django默認(rèn)啟用csrf防護(hù),只針對post請求生效;
?????? 在表單post提交數(shù)據(jù)時(shí)附加上? {% csrf token %}? 標(biāo)簽可禁止csrf偽造。
防御原理:
1)渲染模板文件時(shí)在頁面生成一個(gè)名字叫做csrfmiddlewaretoken的隱藏域。
2)服務(wù)器交給瀏覽器保存一個(gè)名字為csrftoken的cookie信息。
3)提交表單時(shí)兩個(gè)值都會(huì)發(fā)給服務(wù)器,服務(wù)器進(jìn)行比對,如果一樣,則csrf驗(yàn)證通過,否則失敗。
5.7、反向解析:
避免網(wǎng)頁名的改變而導(dǎo)致大規(guī)模改動(dòng)名稱,動(dòng)態(tài)生成url地址:<a href="{% url 'booktest:index' %}">首頁</a>
若urls中的url帶name捕獲的位置參數(shù),則在動(dòng)態(tài)生成地址時(shí)需要明確指定。
eg:
?????? urls:
url(r'^show_args/(\d+)/(\d+)$', views.show_args, name='show_args')?????? views:
def show_args(request,a,b):return HttpResponse(a+':'+b)?????? html:動(dòng)態(tài)產(chǎn)生/show_args/1/2:
<a href="{% url 'booktest:show_args' 1 2 %}">首頁</a>在重定向時(shí)使用反向解析:
from django.core.urlresolvers import reverse無參數(shù):reverse('namespace 名字: name 名字')
有位置參數(shù):reverse('namespace 名字: name 名字',args=位置參數(shù)元組)
六、其他
6.1、靜態(tài)文件:
應(yīng)用文件下創(chuàng)建static文件夾,在settings里配置
STATIC_URL = '/static/' # HTML頁面訪問靜態(tài)文件對應(yīng)的url地址 STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]HTML頁面頂部{% load staticfiles %}
<img src="{% static 'images/a.jpg' %}">
6.2、中間件:
干預(yù)和請求問答過程:
?????? 使用request對象META屬性在view視圖里獲取瀏覽器端ip地址:request.META[' REMOTE_ADDR ']
?????? 新建middleware.py中間件(在視圖函數(shù)調(diào)用之前被調(diào)用,裝飾器寫法):
class BlockedIPSMiddleware(boject):EXCLUDE_IPS = ['10.10.66.110'] #被禁止訪問的ip地址def process_view(request, view_func, *view_args, **view_kwargs):user_ip = request.META[' REMOTE_ADDR ']if user_ip in BlockedIPSMiddleware.EXCLUDE_IPS:return HttpResponse('<h1>Forbidden</h1>')?????? 需要在settings里的MIDDLEWARE_CLASSES里注冊此類:'booktest.middleware.BlockedIPSMiddleware',
??????
中間件處理流程:
?
圖四:中間件處理流程圖
middleware.py:
?????? class TestMiddleware(object):
????????????? __init__:服務(wù)器響應(yīng)第一個(gè)請求時(shí)調(diào)用;
????????????? process_request:產(chǎn)生request對象
????????????? process_view:url匹配后,調(diào)用視圖函數(shù)之前;
????????????? process_response(self, request, response):視圖函數(shù)調(diào)用之后,內(nèi)容返回給瀏覽器之前;
????????????? process_exception:視圖哈數(shù)出現(xiàn)異常,會(huì)調(diào)用此函數(shù)。
?????? ?????? 如果注冊的多個(gè)中間件類中包含process_exception函數(shù)時(shí),調(diào)用的順序和注冊的順序相反,從下往上,所有異常都是從下往上回找。
6.3、上傳文件:
settings配置保存文件目錄:MEDIA_ROOT = os.path.join(BASE_DIR, 'static/media')
后臺(tái)管理上傳圖片:
?????? 設(shè)計(jì)models模型類:
? ? ??
class PicTest(models.Model):goods_pic = models.ImageField(upload_to = 'booktest')?????? 遷移類文件,注冊模型類即完成
?
用戶自定義頁面上傳:
?????? 表單上傳,HTML頁面:
? ? ? ? ? ? ??
<form method="post" enctype="multipart/form-data" action="/upload_handle">{#enctype指定所有的值 都是以二進(jìn)制進(jìn)行傳遞#} {% csrf_token %}<input type="file" name="pic"><input type="submit" value="上傳"></form>?????? views.py接收:使用reqeust對象的FILES屬性,類似于字典,上傳文件不大于2.5M,文件存放在內(nèi)存中,上傳文件大于2.5M,文件內(nèi)容寫到一個(gè)臨時(shí)文件中。request.FILES只有在請求方法為POST,且發(fā)送請求的form擁有enctype="multipart/form-data" 屬性,才會(huì)包含數(shù)據(jù)。
? ? ? ? ? ??
def upload_handle(request):pic = request.FILES['pic'] # 獲取處理對象 save_path = '%s/booktest/%s'%(settings.MEDIA_ROOT, pic.name) #保存路徑with open(save_path, 'wb') as f:for content in pic.chunks(): #一次返回文件的一塊內(nèi)容 f.write(content)PicTest.objects.create(goods_pic='booktest%s'.pic.name)return HttpResponse("上傳成功!")?
6.4、分頁:
? ?
from django.core.paginator import Paginatorpaginator=Paginator(areas, 10) #按每頁10條數(shù)據(jù)進(jìn)行分頁?
?????? Paginator類對象的屬性:
| 屬性名 | 說明 |
| num_pages | 返回分頁之后的總頁數(shù) |
| page_range | 返回分頁后頁碼的列表 |
?
?????? Paginator類對象的方法:
| 方法名 | 說明 |
| page(self, number) | 返回第number也的Page類實(shí)例對象 |
?
?????? Page類對象的方法:
| 屬性名 | 說明 |
| has_previous | 判斷當(dāng)前頁是否有前一頁 |
| has_next | 判斷當(dāng)前頁是否有下一頁 |
| previous_page_number | 返回前一頁的頁碼 |
| next_page_number | 返回下一頁的頁碼 |
?????? booktest/urls.py:
url(r'^show_area(?P<pindex>\d*)$', view.show_area), #分頁,接收頁面?zhèn)鱽淼捻摯a?????? views.py:
from django.core.paginator import Paginatordef show_area(request, pindex):ares = AreaInfo.objects.filter(aParent__isnull=True) #查詢信息 paginator = Paginator(ares, 10)if pindex =='':pindex = 1 #默認(rèn)取第一頁內(nèi)容else:pindex = int(pindex)page = paginator.page(pindex) #獲取第i頁內(nèi)容return render(request, 'booktest/show_area.html', {'page': page})?
?????? HTML:
<ul>{% for area in page.object_list %}或者{% for area in page %}<li>{{ area.atitle }}</li>{% endfor %}</ul>{% if page.has_previous %}<a href="/show_area{{ page.previous_page_number }}"><上一頁</a>{% endif %}{% for pindex in page.paginator.page_range %}{% if pindex == page.num %}{{ pindex }}{% else %}<a href="/show_area{{ pindex }}">{{ pindex }}</a>{% endfor %}{% if page.has_next %}<a href="/show_area{{ page.next_page_number }}"><下一頁</a>{% endif %}?Word文檔筆記看起更爽更全面:可聯(lián)系作者
?
轉(zhuǎn)載于:https://www.cnblogs.com/Jery-9527/p/10745798.html
總結(jié)
以上是生活随笔為你收集整理的Python——Django学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 个人永久性免费-Excel催化剂功能第2
- 下一篇: Python 学习笔记(2)字典默认值和