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