引用自:https://blog.csdn.net/weixin_42950386/article/details/83143293css
定義模型類
模型類被定義在"應用/models.py"文件中,此例中爲"booktest/models.py"文件。
模型類必須繼承自Model類,位於包django.db.models中。
提示:對於重要數據使用邏輯刪除。html
示例演示
接下來首先以"圖書-英雄"管理爲例進行演示。
注意:這裏咱們用的版本是django==1.8.2版本。
瞭解和2.1版本的區別,請百度查詢,這裏再也不囉嗦。python
1.下載pymysql
pip install pymysql
設置test2/__init__.py文件mysql
1 import pymysql 2 pymysql.install_as_MySQLdb()
配置數據庫在settings.py中:ajax
DATABASES = { 'default': { # 'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.mysql', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 'NAME': 'test2', 'USER': 'root', 'PASSWORD': 'mysql', 'PORT': 3306, 'HOST': 'localhost', } }
2.打開booktest/models.py文件,定義模型類以下
1 from django.db import models 2 # from datetime import date 3 # Create your models here. 4 5 class BookInfo(models.Model): 6 """圖書模型類""" 7 # 書名 8 btitle = models.CharField(max_length=40) 9 # 出版日期 10 bpub_date = models.DateField(default='1970-01-01') 11 # 閱讀量 12 bread = models.IntegerField(default=0) 13 # 點贊量 14 bgood = models.IntegerField(default=0) 15 # 刪除 16 is_del = models.BooleanField(default=False) 17 18 class HeroInfo(models.Model): 19 """英雄模型類""" 20 # 英雄名稱 21 hname = models.CharField(max_length=20) 22 # 性別 23 hgender = models.BooleanField(default=False) # False爲男 24 # 年齡 25 hage = models.IntegerField(default=18) 26 # 功夫 27 hcomment = models.CharField(max_length=128) 28 # 關聯 29 hbook = models.ForeignKey("BookInfo") 30 # 刪除 31 isDelete = models.BooleanField(default=False)
3.遷移
生成遷移文件。正則表達式
建立數據庫sql
python manage.py makemigrations數據庫
報錯django
解決方案:ubuntu
看一下settings.py文件 apps中有沒有添加 booktest
而後執行以下命令。
python manage.py makemigrations
python manage.py migrate
遷移
打開數據庫的命令行,查看當前全部表以下圖:
遷移
表bookinfo結構如:
默認值並不在數據庫層面生效,而是在django建立對象時生效。
圖書表結構
表booktest_heroinfo結構以下:
Django框架會根據關係屬性生成一個關係字段,並建立外鍵約束。
英雄表結構
測試數據
在數據庫命令行中,複製以下語句執行,向booktest_bookinfo表中插入測試數據:
insert into booktest_bookinfo(btitle,bpub_date,bread,bcomment,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);
再複製以下語句執行,向booktest_heroinfo表中插入測試數據:
insert into booktest_heroinfo(hname,hgender,hbook_id,hcomment,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);
4,後臺管理
打開test1/settings.py文件,找到語言編碼、時區的設置項,將內容改成以下
LANGUAGE_CODE = 'zh-hans' #使用中國語言 TIME_ZONE = 'Asia/Shanghai' #使用中國上海時間
admin.py文件中:
1 from django.contrib import admin 2 from booktest.models import * 3 # Register your models here. 4 5 # 關聯對象 6 # 1.以塊的形式嵌入 7 # 建立StackedInline類 8 class BookStackedInline(admin.StackedInline): 9 # 寫多類的名字 10 model = HeroInfo 11 # 額外設置編輯子對象 默認爲3個 12 extra = 2 # 額外編輯兩個對象 13 14 # 2.以表格的形式嵌入 15 class BookTabularInline(admin.TabularInline): 16 # 寫多類的名字 17 model = HeroInfo 18 # 額外設置編輯子對象 默認爲3個 19 extra = 2 # 額外編輯兩個對象 20 21 22 class BookInfoAdmin(admin.ModelAdmin): 23 # 每頁顯示多少條數據 24 list_per_page = 10 25 # 頂部顯示的屬性,設置爲True在頂部顯示,設置爲False不在頂部顯示,默認爲True 26 actions_on_top = True 27 # 底部顯示的屬性,設置爲True在底部顯示,設置爲False不在底部顯示,默認爲False 28 actions_on_bottom = True 29 # 自定義顯示字段 30 # list_display = [模型字段1,模型字段2....] 模型字段能夠是BookInfo裏面設置的屬性名 也能夠是方法名 31 list_display = ['id', 'btitle', 'bpub_date', 'title'] 32 # 方法列排序 在models.py文件 33 # 右側欄過濾器 34 list_filter=['btitle'] # 以btitle 過濾 35 # 搜索框 36 search_fields = ['btitle'] # 以btitle字段搜索 37 # 關聯BookStackedInline類 塊類 38 # inlines = [BookStackedInline] 39 # 關聯BookTabularInline類 40 inlines = [BookTabularInline] 41 42 class HeroInfoAdmin(admin.ModelAdmin): 43 list_display = ['id', 'hname', 'hcomment'] 44 45 46 class AreaInfoAdmin(admin.ModelAdmin): 47 list_display = ['id', 'atitle', 'parent'] 48 # 編輯頁 49 # 添加/修改頁面字段順序 50 # fields = ['aParent', 'atitle'] 51 # 分組顯示 fieldsets=() 後面跟元祖 52 # 與fields=[] 不能同時使用 53 fieldsets = ( 54 ('基本', {'fields':['aParent']}), 55 ('高級', {'fields':['atitle']}) 56 ) 57 58 59 60 # 註冊 61 admin.site.register(BookInfo, BookInfoAdmin) 62 admin.site.register(HeroInfo, HeroInfoAdmin) 63 admin.site.register(AreaInfo, AreaInfoAdmin)
models.py文件中各類方法
1 from django.db import models 2 from datetime import date 3 # Create your models here. 4 # 創建一個Manager類 5 class InfoManager(models.Manager): 6 """管理器類""" 7 # 改變查詢的結果 8 def all(self): 9 # 1.調用父類結果 10 result = super().all() 11 # 改變結果 12 return result.filter(isDelete=False) 13 14 def create_book(self, btitle, bpub_date): 15 # 獲取模型所在的模型類 16 model_class = self.model 17 # 建立對象 18 book = model_class() 19 book.btitle = btitle 20 book.bpub_date = bpub_date 21 book.save() 22 return book 23 24 25 class BookInfo(models.Model): 26 """圖書模型類""" 27 # 書名 28 # btitle = models.CharField(max_length=20,verbose_name='書名') # verbose_name= 給列標題更名 29 btitle = models.CharField('書名',max_length=20) # 也能夠第一個參數放中文標題 不用加verbose_name= 30 # 出版時間 31 bpub_date = models.DateField() 32 # 閱讀量 33 bread = models.IntegerField(default=0) 34 # 評論數 35 bcomment = models.IntegerField(default=0) 36 # 是否刪除 37 isDelete = models.BooleanField(default=False) 38 # 創建manager對象 39 objects = InfoManager() 40 41 # 將方法作列 42 def title(self): 43 return self.btitle 44 # 方法列排序 45 title.admin_order_field='btitle' 46 # 方法列標題更名 47 title.short_description = '書名(方法列)' 48 49 50 class HeroInfo(models.Model): 51 """英雄模型類""" 52 # 名字 53 hname = models.CharField(max_length=20) 54 # 性別 55 hgender = models.BooleanField(default=False) 56 # 功夫 57 hcomment = models.CharField(max_length=128) 58 # 書名 59 hbook = models.ForeignKey('BookInfo') 60 # 是否刪除 61 isDelete = models.BooleanField(default=False) 62 63 64 class AreaInfo(models.Model): 65 """地區模型類""" 66 # 地區名 67 atitle = models.CharField(max_length=20) 68 # 關係屬性 表明當前地區父類地區 69 aParent = models.ForeignKey('self', null=True, blank=True) 70 71 def __str__(self): 72 return self.atitle 73 74 # 封裝方法 訪問關聯對象成員 75 def parent(self): 76 if self.aParent is None: 77 return '' 78 else: 79 return self.aParent.atitle 80 81 parent.short_description = '父級區域名稱'
重寫模板
1)在templates/目錄下建立admin目錄,結構以下圖:
2)打開當前虛擬環境中Django的目錄,再向下找到admin的模板,目錄以下:
/home/python/.virtualenvs/py_django/lib/python3.5/site-packages/django/contrib/admin/templates/admin
編輯base_site.html文件:
{% extends "admin/base.html" %} {% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %} {% block branding %} <h1 id="site-name"><a href="{% url 'admin:index' %}">{{ site_header|default:_('Django administration') }}</a></h1> <hr> <h1>自定義的管理頁模板</h1> <hr> {% endblock %} {% block nav-global %}{% endblock %}
建立管理員
終端中命令以下:
python manage.py createsuperuser
根據提示輸入管理員、郵箱、密碼
啓動服務器
python manage.py runserver
打開瀏覽器,在地址欄中輸入以下地址後回車
http://127.0.0.1:8000/admin/
輸入創建的管理員和密碼登陸
4.定義視圖
打開booktest/views.py文件,定義視圖代碼以下:
1 from django.shortcuts import render, redirect # redircet重定向 2 from booktest.models import * 3 from datetime import date 4 from django.http import HttpRequest, HttpResponse 5 # Create your views here. 6 def index(request): 7 8 # 查看全部書 9 list = BookInfo.objects.all() 10 return render(request, 'booktest/index.html', {'list': list}) 11 12 def create(request): 13 14 b = BookInfo() 15 b.btitle = '流星蝴蝶劍' 16 b.bpub_date = date(1989,2,1) 17 b.save() 18 return redirect(index) # 跳轉回首頁 19 20 def delete(request, bid): 21 22 b = BookInfo.objects.get(id=bid) 23 b.delete() 24 return redirect(index) 25 26 def books(request, bid): 27 b = BookInfo.objects.get(id=bid) 28 list = b.heroinfo_set.all() 29 30 return render(request, 'booktest/detail.html', {'list':list,'book':b})
5.配置url
打開test2/urls.py文件,配置url以下:
1 from django.conf.urls import include, url 2 from django.contrib import admin 3 4 urlpatterns = [ 5 url(r'^admin/', include(admin.site.urls)), 6 # 引入booktest的url配置 7 url(r'^', include('booktest.urls')), # booktest.urls要加引號,否則找不到文件 ? 8 ]
在booktest應用下建立urls.py文件,代碼以下:
1 from django.conf.urls import include, url 2 from django.contrib import admin 3 from booktest import views 4 5 urlpatterns = [ 6 url(r'^index$', views.index), 7 url(r'^create$', views.create), 8 # 傳值用() 擴起來 如:(\d+) 9 url(r'^delete/(\d+)$', views.delete), 10 url(r'^books/(\d+)$', views.books), 11 ]
6.建立模板
打開test2/settings.py文件,配置模板查找目錄TEMPLATES的DIRS。
‘DIRS’: [os.path.join(BASE_DIR,‘templates’)],
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR,'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
模板目錄
建立templates/booktest/index.html文件。
模板文件
渲染模板index.html:
<a href="/create">新增</a> <ul> {% for book in list %} <li><a href="/books/{{ book.id }}">{{ book.btitle }}</a> --- <a href="/delete/{{ book.id }}">刪除</a></li> {% endfor %} </ul>
7.運行 運行服務器。
python manage.py runserver (主機名 端口號) 括號裏能夠省去
在瀏覽器中查看。
首頁
操做效果以下圖。
運行
在mysql命令行中查看數據表變化以下圖:
數據變化
靜態文件配置
在settings.py文件中定義靜態文件存放的物理目錄
STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ]
在項目根目錄下建立static目錄,再建立img、css、js目錄
ajax登陸提示403
這是csrf機制致使的 打開settings.py
MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', # 把這行註釋了就能夠了 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', )
模板繼承
繼承格式:{% extends 父模板文件路徑%}
例:
{% extends 'layout/header.html' %} {% block 塊名 %} {{ block.super}} #獲取父模板中塊的默認內容 重寫的內容 {% endblock 塊名%}
html轉義
要關閉模板上下文字符串的轉義: 能夠使用 {{ 模板變量|safe}} 也能夠使用: {% autoescape off %} 模板語言代碼 {% endautoescape %} 模板硬編碼中的字符串默認不會通過轉義,若是須要轉義,那須要手動進行轉義
驗證碼
1)安裝包
pip install Pillow==3.4.1
2)在booktest/views.py文件中,建立視圖verify_code
1 from PIL import Image, ImageDraw, ImageFont 2 from django.utils.six import BytesIO 3 ... 4 def verify_code(request): 5 #引入隨機函數模塊 6 import random 7 #定義變量,用於畫面的背景色、寬、高 8 bgcolor = (random.randrange(20, 100), random.randrange( 9 20, 100), 255) 10 width = 100 11 height = 25 12 #建立畫面對象 13 im = Image.new('RGB', (width, height), bgcolor) 14 #建立畫筆對象 15 draw = ImageDraw.Draw(im) 16 #調用畫筆的point()函數繪製噪點 17 for i in range(0, 100): 18 xy = (random.randrange(0, width), random.randrange(0, height)) 19 fill = (random.randrange(0, 255), 255, random.randrange(0, 255)) 20 draw.point(xy, fill=fill) 21 #定義驗證碼的備選值 22 str1 = 'ABCD123EFGHIJK456LMNOPQRS789TUVWXYZ0' 23 #隨機選取4個值做爲驗證碼 24 rand_str = '' 25 for i in range(0, 4): 26 rand_str += str1[random.randrange(0, len(str1))] 27 #構造字體對象,ubuntu的字體路徑爲「/usr/share/fonts/truetype/freefont」 28 font = ImageFont.truetype('FreeMono.ttf', 23) 29 #構造字體顏色 30 fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255)) 31 #繪製4個字 32 draw.text((5, 2), rand_str[0], font=font, fill=fontcolor) 33 draw.text((25, 2), rand_str[1], font=font, fill=fontcolor) 34 draw.text((50, 2), rand_str[2], font=font, fill=fontcolor) 35 draw.text((75, 2), rand_str[3], font=font, fill=fontcolor) 36 #釋放畫筆 37 del draw 38 #存入session,用於作進一步驗證 39 request.session['verifycode'] = rand_str 40 #內存文件操做 41 buf = BytesIO() 42 #將圖片保存在內存中,文件類型爲png 43 im.save(buf, 'png') 44 #將內存中的圖片數據返回給客戶端,MIME類型爲圖片png 45 return HttpResponse(buf.getvalue(), 'image/png')
3)打開booktest/urls.py文件,配置url
url(r'^verify_code/$', views.verify_code),
調用驗證碼
1)在booktest/views.py文件中,建立視圖verify_show。
def verify_show(request): return render(request,'booktest/verify_show.html')
2)打開booktest/urls.py文件,配置url。
url(r'^verify_show/$', views.verify_show),
3)在templates/booktest/目錄下建立verify_show.html。
<html> <head> <title>驗證碼</title> </head> <body> <form method="post" action="/verify_yz/"> {%csrf_token%} <input type="text" name="yzm"> <img id="yzm" src="/verify_code/"/> <span id="change">看不清,換一個</span> <br> <input type="submit" value="提交"> </form> </body> </html>
驗證
1)在booktest/views.py文件中,建立視圖verify_yz。
1 def verify_yz(request): 2 yzm=request.POST.get('yzm') 3 verifycode=request.session['verifycode'] 4 response=HttpResponse('no') 5 if yzm==verifycode: 6 response=HttpResponse('ok') 7 return response
2)打開booktest/urls.py文件,配置url。
url(r'^verify_yz/$', views.verify_yz),
反向解析
當某一個url配置的地址發生變化時,頁面上使用反向解析生成地址的位置不須要發生變化。
根據url 正則表達式的配置動態的生成url。
在項目urls中包含具體應用的urls文件時指定namespace;
在應用的urls中配置是指定name;
在模板文件中使用時,格式以下:
{% url 'namespace名字:name' %} 例如{% url 'booktest:fan2'%}
帶位置參數:
{% url 'namespace名字:name' 參數 %} 例如{% url 'booktest:fan2' 1%}
帶關鍵字參數:
{% url 'namespace名字:name' 關鍵字參數 %} 例如{% url 'booktest:fan2' id=1 %}
在重定向的時候使用反向解析:
from django.core.urlresolvers import reverse
無參數:
reverse('namespace名字:name名字')
若是有位置參數
reverse('namespace名字:name名字', args = 位置參數元組)
若是有關鍵字參數
reverse('namespace名字:name名字', kwargs=字典)
中間件
1) 新建middleware.py文件。
2) 定義中間件類。
在類中定義中間件預留函數。
__init__:服務器響應第一個請求的時候調用。
process_request:是在產生request對象,進行url匹配以前調用。
process_view:是url匹配以後,調用視圖函數以前。
process_response:視圖函數調用以後,內容返回給瀏覽器以前。
process_exception:視圖函數出現異常,會調用這個函數。
若是註冊的多箇中間件類中包含process_exception函數的時候,調用的順序跟註冊的順序是相反的。
3) 註冊中間件類。
圖片上傳