您好,登錄后才能下訂單哦!
MVC的產生理念:分工。讓專門的人去做專門的事。
MVC的核心思想:解耦
M:model模型,和數據庫進行交互
V:view視圖,產生HTML頁面
C:controller控制器,接收請求,進行處理,與M,V進行交互,返回應答
本質上還是MVC的思想
M:model模型,和MVC中M功能相同,和數據庫進行交互
V:View視圖,和MVC中C功能相同,接收請求,進行處理,與M和T進行交互,返回應答
T:template模板,和MVC中V功能相同,產生HTML頁面
pip install virtualenv #安裝虛擬環境
pip install virtualenvwrapper #安裝虛擬環境擴展包
vim .bashrc #添加以下兩行
export WORKON_HOME=$HOME/.vitualenvs
source /usr/bin/virtualenvwrapper.sh
使用source .bashrc使其生效
創建python3虛擬環境
mkvirtualenv -p python3 虛擬環境名
workon 虛擬環境名 #進入虛擬環境
deactivate #退出虛擬環境
命令:django-admin startproject myobj
init:說明myobj是一個python包
settings.py:項目的配置文件
urls.py:進行url路由的配置
wsgi.py:web服務器和Django交互的入口
manage.py:項目的管理文件
命令:python manage.py startapp appname
init .py:說明目錄是一個Python模塊
models.py:寫和數據庫項目的內容
views.py:接收請求,進行處理,與M和T進行交互,返回應答。定義處理函數,視圖函數
test.py:寫測試代碼文件
admin.py:網站后臺管理相關的文件
修改settings.py的INSTALLED_APPS的內容,添加應用名字
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'test1',
]
python manage.py runserver
訪問127.0.0.1:8000可以查看創建的應用
修改settings.py文件
LANGUAGE_CODE = 'zh-hans' #使用中文
TIME_ZONE = 'Asia/Shanghai' #中國時區
命令:python manage.py createsuperuser
登錄后臺
瀏覽器輸入"127.0.0.1/admin"進入后臺管理頁面
在應用下的admin.py下注冊模型類
告訴Django框架根據注冊的模型來生成對應表管理頁面
b=Bookinfo()
str(b)
class AreaInfoAdmin(admin.ModelAdmin):
'''地區模型管理類'''
list_per_page=10 #指定每頁顯示10條數據
頂部顯示的屬性,設置為True在頂部顯示,設置為False不在頂部顯示,默認為Trueactions_on_top=True
底部顯示的屬性,設置為True在底部顯示,設置為False不在底部顯示,默認為Falseactions_on_bottom=False
屬性如下:list_display=[模型字段1,模型字段2,...]
方法列是不能排序的,如果需要排序需要為方法指定排序依據admin_order_field=模型類字段
打開booktest/models.py文件,修改AreaInfo類如下:
class AreaInfo(models.Model):
...
def title(self):
return self.atitle
title.admin_order_field='atitle'
列標題默認為屬性或方法的名稱,可以通過屬性設置。需要先將模型字段封裝成方法,再對方法使用這個屬性,模型字段不能直接使用這個屬性short_description='列標題'
vim booktest/models.py文件,修改AreaInfo類如下:
class AreaInfo(models.Model):
...
title.short_description='區域名稱'
屬性如下,只能接收字段,會將對應字段的值列出來,用于快速過濾。一般用于有重復值的字段。list_filter=[]
屬性如下,用于對指定字段的值進行搜索,支持模糊查詢。列表類型,表示在這些字段上進行搜索。search_fields=[]
屬性如下:fields=[]
vim booktest/admin.py
class AreaAdmin(admin.ModelAdmin):
...
fields=['aprent','atitle']
屬性如下:
fieldset=(
('組1標題',{'fields':('字段1','字段2')}),
('組2標題',{'fields':('字段3','字段4')}),
)
vim booktest/admin.py文件,修改AreaAdmin類如下:
class AreaAdmin(admin.ModelAdmin):
...
#fields=['aparent','atitle']
fieldsets=(
('基本',{'fields':['atitle']}),
('高級',{'fields':['aparent']})
)
在一對多的關系中,可以在一端的編輯頁面中編輯多端的對象,嵌入多端對象的方式包括表格、塊兩種。類型InlineModelAdmin:表示在模型的編輯頁面嵌入關聯模型的編輯。子類Tabularlnline:以表格的形式嵌入。子類StackedInline:以塊的形式嵌入。
打開booktest/admin.py文件,創建AreaStackedInline類。
class AreaStackedInline(admin.StackedInline):
model=AreaInfo #關聯子對象
extra=2 #額外編輯2個子對象
打開booktest/admin.py文件,修改AreaAdmin類如下:
class AreaAdmin(admin.ModelAdmin):
...
inlines=[AreaStackedInline]
Object:對象-類
Mapping:映射,建立類與表的對應關系
Relation:關系,關系數據庫中的表
Django中內嵌了orm框架,orm框架可以通過類和對象操作對應的數據表,不需要寫sql語句
創建模型類
#圖書類
class BookInfo(models.Model):
'''圖書模型類'''
#圖書名稱,Charfield說明是一個字符串,max_length指定字符串的最大長度
btitle=models.CharField(max_length=20)
#出版日期,DateField說明是一個日期類型
bpub_date=models.DateField()
orm另外一個作用:根據設計的類生成數據庫中的表
往表中添加數據
python manage.py shell
>>> from test1.models import BookInfo
>>> b=BookInfo()
>>> b.btitle='天龍八部'
>>> from datetime import date
>>> b.bpub_date=date(1990,1,1)
>>> b.save()
>>> BookInfo.objects.get(id=1)
<BookInfo: BookInfo object (1)>
>>> b2=BookInfo.objects.get(id=1)
>>> b2.btitle
'天龍八部'
>>> b2.bpub_date
datetime.date(1990, 1, 1)
>>> b2.id
1
>>> b2.bpub_date=date(2019,1,1)
>>> b2.save()
>>> b3=BookInfo.objects.get(id=1)
>>> b3.bpub_date
datetime.date(2019, 1, 1)
>>> b2.delete()
(1, {'test1.BookInfo': 1})
vim models.py
class HeroInfo(models.Model):
hname =models.CharField(max_length=20) #英雄名稱
#性別,Booleanfield說明是bool類型,default指定默認值,False代表男
hgender=models.BooleanField(default=False)
#備注
hcomment=models.CharField(max_length=128)
#關系屬性 hbook,建立圖書類和英雄人物類之間的一對多關系
#關系屬性對應的表的字段名格式:關系屬性名_id
hbook=models.ForeignKey('BookInfo',on_delete=models.CASCADE,)
生成遷移文件 python3 manage.py makemigrations
執行遷移文件生成表python3 manage.py migrate
往表中操作數據python manage.py shell
from test1.models import BookInfo,HeroInfo
b=BookInfo()
b.btitle='天龍八部'
from datetime import date
b.bpub_date=date(1990,1,1)
b.save()
h=HeroInfo()
h.hname='段譽'
h.hgender=False
h.hcomment='六脈神劍'
h.hbook=b
h.save()
h3=HeroInfo()
h3.hname='喬峰'
h3.hcomment='降龍十八掌'
h3.hbook=b
h3.save()
h4=HeroInfo.objects.get(id=2)
h4.hname
'喬峰'
h4.hgender
False
h4.hcomment
'降龍十八掌'
h4.hbook_id
3
h4.hbook.btitle
'天龍八部'
使用時需要引入django.db.models包,字段類型如下:
類型 | 描述 |
---|---|
AutoField | 自動增長的integerfield,通常不用指定,不指定是Django會自動創建屬性名為id的自動增長屬性 |
BooleanField | 布爾字段,值為True或False |
NullBooleanField | 支持Null、True、False三種值 |
CharField(max_length=最大長度) | 字符串,參數max_length表示最大字符個數 |
TextField | 大文本字段,一般超過4000個 |
IntegerField | 整數 |
DecimalField(max_digits=None,decimal_place=None) | 十進制浮點數。參數max_digits表示總位。參數decimal_places表示小數位數 |
FloatField | 浮點數。參數同上 |
DateField:([auto_now=False,auto_now_add=False]) | 日期。1.參數auto_now表示每次保存對象時,自動設置該字段為當前時間,用于“最后一次修改”的時間戳,他總是使用當前日期,默認為false。2.參數auto_now_add表示當對象第一次被創建時自動設置當前時間,用于創建的時間戳,他總是使用當前日期,默認為false。3.參數auto_now_add 和auto_now是相互排斥的,組合將會發生錯誤。 |
TimeField | 時間,參數同datefield |
DateTimeField | 日期時間,參數同DateField |
FileField | 上傳文件字段 |
ImageField | 繼承于FileField,對上傳的內容進行校驗,確保是有效的圖片 |
通過選項實現對字段的約束,選項如下:
選項名 | 描述 |
---|---|
default | 默認值,設置默認值 |
primary_key | 若為True,則該字段會成為模型的主鍵字段,默認值為false,一般作為autofield的選項使用 |
unique | 如果為True,這個字段在表中必須唯一值,默認值是false |
db_index | 若值為True,則在表中會為此字段創建索引,默認值是false |
db_column | 字段的名稱,如果未指定,則使用屬性的名稱 |
null | 如果為True,表示允許為空,默認值是false |
blank | 如果為True,則該字段允許為空白,默認值是false |
vim test1/urls.py
urlpatterns =[
#通過url函數設置url路由配置項
url(r'^index$',views.index), # 建立index和視圖之間的關系
url(r'^index2$',views.index2),
url(r'^books$',views.show_books), #顯示圖書信息
url(r'^books/(\d+)$',views.detail), #顯示英雄信息
]
vim views.py
def show_books(request):
'''顯示圖書的信息'''
#1.通過M查找圖書表中的數據
books=BookInfo.objects.all()
#2.使用模板
return render(request,'test1/show_books.html',{'books':books})
def detail(request,bid):
'''查詢圖書關聯英雄信息'''
#1.根據bid查詢圖書信息
book=BookInfo.objects.get(id=bid)
#2.查詢和book關聯的英雄信息
heros=book.heroinfo_set.all()
#3.使用模板
return render(request,'test1/detail.html',{'book':book,'heros':heros})
vim templates/test1/show_books.html
<!DOCTYPE>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>顯示圖書信息</title>
</head>
<body>
圖書信息如下:
<ul>
{% for book in books %}
<li><a href="/books/{{ book.id }}">{{ book.btitle }}</a></li>
{% endfor %}
</ul>
</body>
</html>
vim detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>顯示圖書關聯的英雄信息</title>
</head>
<body>
<h2>{{ book.btitle }}</h2>
英雄信息如下:<br/>
<ul>
{% for hero in heros %}
<li>{{ hero.hname }}--{{ hero.hcomment }}</li>
{% empty %}
<li>沒有英雄信息</li>
{% endfor %}
</ul>
</body>
</html>
vim settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'booktest', #注冊應用
]
DATABASES = {
'default': {
#'ENGINE': 'django.db.backends.sqlite3',
#'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.mysql',
'NAME': 'booktest', #使用的數據庫名字
'USER': 'root', #mysql用戶名
'PASSWORD': 'root', #mysql密碼
'HOST': 'localhost', #mysql主機
'PORT': 3306,
}
}
創建數據庫
create database booktest charset=utf8;
安裝pymysql
pip install pymysql
vim __init__.py
ALLOWED_HOSTS = ['60.205.177.168']
from test1.models import BookInfo
# Register your models here.
#注冊模型類
admin.site.register(BookInfo)
vim models.py
class BookInfo(models.Model):
'''圖書模型類'''
btitle=models.CharField(max_length=20)
#出版日期,DateField說明是一個日期類型
bpub_date=models.DateField()
def __str__(self):
#返回書名
return self.btitle
class BookInfoAdmin(admin.ModelAdmin):
'''圖書模型管理類'''
list_display=['id','btitle','bpub_date']
class HeroInfoAdmin(admin.ModelAdmin):
'''英雄模型人物類'''
list_display=['id','hname','hcomment']
#注冊模型類
admin.site.register(BookInfo,BookInfoAdmin)
admin.site.register(HeroInfo,HeroInfoAdmin)
在Django中,通過瀏覽器去請求一個頁面時,使用視圖函數來處理這個請求的,視圖函數處理之后,要給瀏覽器返回頁面內容
返回HTML內容httpresponse,也可能重定向redirect
視圖函數定義在views.py中
視圖函數必須有一個參數request,是一個httprequest類型的對象,參數名可以變化,進行處理之后,需要返回一個HttpResponse的類對象,hello,python就是返回給瀏覽器顯示的內容
例:
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
#1.定義視圖函數,HttpRequest
#2.進行url配置,建立url地址和視圖的對應關系
#http://127.0.0.1:8000/index
def index(request):
#進行處理,和M,T進行交互
return HttpResponse('老鐵沒毛病')
def index2(request):
return HttpResponse('hello python')
url配置的目的是建立url和視圖函數的對應關系。url配置項定義在urlpatterns的列表中,每一個配置項都調用url函數。
url函數有兩個參數,第一個參數是一個正則表達式,第二個是對應的處理動作。
配置url時,有兩種語法格式:
在項目的urls.py文件中包含具體應用的urls.py文件,應用的urls.py文件中寫url和視圖函數的對應關系
當用戶輸入如127.0.0.1:8000/index時,去除域名和最前面的/,剩下index,拿index字符串到項目的urls文件中進行匹配,配置成功之后,繼續到項目中的urls文件中進行正則匹配,匹配成功之后執行視圖函數index,index視圖函數返回內容hello python 給瀏覽器來顯示
vim /myobj/urls.py
from django.contrib import admin
#from django.urls import path
from django.conf.urls import include,url
urlpatterns = [
url(r'^admin/',admin.site.urls),#配置項
url(r'^',include('test1.urls')) #包含test1應用中的urls文件
]
vim test1/urls.py
from django.conf.urls import url
from test1 import views
# /index
#在應用的urls文件中進行url配置的時候:
#1.嚴格匹配開頭和結尾
urlpatterns =[
#通過url函數設置url路由配置項
url(r'^index$',views.index), # 建立index和視圖之間的關系
url(r'^index2$',views.index2),
]
404:找不到頁面,關閉調試模式之后,默認會顯示一個標準的錯誤頁面,如果要顯示自定義的頁面,則需要templates目錄下面自定義一個404.html文件
進行url匹配時,把所需要的捕獲的部分設置成一個正則表達式組,這樣Django框架就會自動把匹配成功后相應組的內容作為參數傳遞給視圖函數。
from django.conf.urls import url
from booktest import views
urlpatterns = [
url(r'^index$',views.index), #首頁,
url(r'^showarg(\d+)$',views.show_arg), #捕獲url參數
]
vim test3/urls.py
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^',include('booktest.urls')),
]
vim booktest/views.py
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
'''首頁'''
return render(request,'booktest/index.html')
def show_arg(request,num):
return HttpResponse(num)
from django.conf.urls import url
from booktest import views
urlpatterns = [
url(r'^index$',views.index), #首頁,
url(r'^showarg(\d+)$',views.show_arg), #捕獲url參數:位置參數
url(r'^showarg(?P<num>\d+)$',views.show_arg), #捕獲關鍵字參數
]
from django.conf.urls import url
from booktest import views
urlpatterns = [
url(r'^index$',views.index), #首頁,
url(r'^showarg(\d+)$',views.show_arg), #捕獲url參數:位置參數
url(r'^showarg(?P<num>\d+)$',views.show_arg), #捕獲關鍵字參數
url(r'^login$',views.login), #顯示登錄頁面
url(r'^login_check$',views.login_check),
]
vim login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄頁面</title>
</head>
<body>
<form method="post" action="/login_check">
用戶名:<input type="text" name="username"><br/>
密碼:<input type="password" name="password"><br/>
<input type="submit" value="登錄">
</form>
</body>
</html>
url | 視圖 | 模板文件 |
---|---|---|
/login | login | login.html |
注釋掉settings.py文件的47行
vim booktest/views.py
from django.shortcuts import render,redirect
from django.http import HttpResponse
# Create your views here.
def index(request):
'''首頁'''
return render(request,'booktest/index.html')
def show_arg(request,num):
return HttpResponse(num)
def login(request):
'''顯示登錄頁面'''
return render(request,'booktest/login.html')
def login_check(request):
'''登錄校驗視圖'''
#request.POST保存的是post方式提交的參數 QueryDict
# request.GET保存的是get方式提交的參數
#1. 獲取提交的用戶名和密碼
username=request.POST.get('username')
password=request.POST.get('password')
#2. 進行登錄的校驗
#實際開發:根據用戶和密碼查找數據庫
#模擬:smart 123
if username=='smart' and password=='123':
#用戶名密碼正確,跳轉到首頁
return redirect('/index')
else:
#用戶名或密碼錯誤,跳轉到登錄頁面
return redirect('/login')
cookie是由服務器生成,存儲在瀏覽器端的一小段文本信息
vim booktest/urls.py
from django.shortcuts import render,redirect
from django.http import HttpResponse
from datetime import datetime,timedelta
# /set_cookie
def set_cookie(request):
'''設置一個cookie信息'''
response=HttpResponse('設置cookie')
# 設置一個cookie信息,名字為num,值為1
response.set_cookie('num',1,max_age=14*24*3600)
#response.set_cookie('num', 1, expires=datetime.now()+timedelta(days=14))
#返回response
return response
# /get_cookie
def get_cookie(request):
'''獲取cookie的信息'''
#取出cookie num的值
num=request.COOKIES['num']
return HttpResponse(num)
vim booktest/urls.py
urlpatterns = [
url(r'^index$',views.index), #首頁,
url(r'^showarg(\d+)$',views.show_arg), #捕獲url參數:位置參數
url(r'^showarg(?P<num>\d+)$',views.show_arg), #捕獲關鍵字參數
url(r'^login$',views.login), #顯示登錄頁面
url(r'^login_check$',views.login_check),
url(r'^set_cookie$',views.set_cookie), #設置cookie
url(r'^get_cookie$',views.get_cookie), #獲取cookie
]
vim login.html
<form method="post" action="/login_check">
用戶名:<input type="text" name="username" value="{{ username }}"><br/>
密碼:<input type="password" name="password"><br/>
<input type="checkbox" name="remember">記住用戶名<br/>
<input type="submit" value="登錄">
</form>
vim booktest/views.py
def login(request):
'''顯示登錄頁面'''
#獲取cookie username
if 'username' in request.COOKIES:
#獲取記住的用戶名
username = request.COOKIES['username']
else:
username=''
return render(request,'booktest/login.html',{'username':username})
def login_check(request):
'''登錄校驗視圖'''
#request.POST保存的是post方式提交的參數 QueryDict
# request.GET保存的是get方式提交的參數
#1. 獲取提交的用戶名和密碼
username=request.POST.get('username')
password=request.POST.get('password')
remember=request.POST.get('remember')
#2. 進行登錄的校驗
#實際開發:根據用戶和密碼查找數據庫
#模擬:smart 123
if username=='smart' and password=='123':
#用戶名密碼正確,跳轉到首頁
response=redirect('/index')
#判斷是否需要記住用戶名
if remember == 'on':
#設置cookie username,過期時間為一周
response.set_cookie('username',username,max_age=7*24*3600)
return response
else:
#用戶名或密碼錯誤,跳轉到登錄頁面
return redirect('/login')
session存儲在服務器端
vim booktest/views.py
#/set_session
def set_session(request):
'''設置session'''
request.session['username']='smart'
request.session['age']=18
return HttpResponse('設置session')
#/get_session
def get_session(request):
'''獲取session'''
username=request.session['username']
age=request.session['age']
return HttpResponse(username+':'+str(age))
#/clear_session
def clear_session(request):
'''清除session信息'''
#request.session.clear()
request.session.flush()
#del request.session['age']
return HttpResponse('清除成功')
vim booktest/urls.py
url(r'^set_session$',views.set_session), #設置session
url(r'^get_session$',views.get_session), #獲取session
url(r'^clear_session$',views.clear_session), #清除session
如果沒有指定過期時間則兩個星期后過期request.sesion.set_expiry(value)
vim views.py
def login(request):
'''顯示登錄頁面'''
#判斷用戶是否登錄
if request.session.has_key('islogin'):
return redirect('/index')
else:
#用戶未登錄
#獲取cookie username
if 'username' in request.COOKIES:
#獲取記住的用戶名
username = request.COOKIES['username']
else:
username=''
return render(request,'booktest/login.html',{'username':username})
def login_check(request):
'''登錄校驗視圖'''
#request.POST保存的是post方式提交的參數 QueryDict
# request.GET保存的是get方式提交的參數
#1. 獲取提交的用戶名和密碼
username=request.POST.get('username')
password=request.POST.get('password')
remember=request.POST.get('remember')
#2. 進行登錄的校驗
#實際開發:根據用戶和密碼查找數據庫
#模擬:smart 123
if username=='smart' and password=='123':
#用戶名密碼正確,跳轉到首頁
response=redirect('/index')
#判斷是否需要記住用戶名
if remember == 'on':
#設置cookie username,過期時間為一周
response.set_cookie('username',username,max_age=7*24*3600)
#記住用戶登錄狀態
#只有session中有islogin,就認為用戶已登錄
request.session['islogin']=True
return response
else:
#用戶名或密碼錯誤,跳轉到登錄頁面
return redirect('/login')
通常是在視圖函數中使用模板產生html內容返回給客戶端
'DIRS': [os.path.join(BASE_DIR,'templates')],
django.template.loaders.filesystem.Loader:/root/wanger/test4/templates/booktest/index2.html(來源不存在)
django.template.loaders.app_directories.Loader:/root/.virtualenvs/wanger/lib/python3.5/site-packages/django/contrib/admin/templates/booktest/index2.html(來源不存在)
django.template.loaders.app_directories.Loader:/root/.virtualenvs/wanger/lib/python3.5/site-packages/django/contrib/auth/templates/booktest/index2.html(來源不存在)
模板語言簡稱為DTL(Django template language)
模板變量名是由數字,字母,下劃線和點組成的,不能以下劃線開頭
模板變量使用:{{ 模板變量名 }}
模板變量的解析順序:
例如:{{ book.btitle }}
把book當成一個對象,把btitle當成對象的方法,進行取值book.btitle
例如:{{book.0}}
from django.db import models
# Create your models here.
class BookInfo(models.Model):
'''圖書模型類'''
#圖書名稱
btitle=models.CharField(max_length=20,db_column='btitle')
#出版日期
bpub_date=models.DateField()
#閱讀量
bread=models.IntegerField(default=0)
#評論量
bcomment=models.IntegerField(default=0)
#刪除標記
isdelete=models.BooleanField(default=False)
vim views.py
from booktest.models import BookInfo
# /temp_var
def temp_var(request):
'''模板變量'''
my_dict={'title':'字典鍵值'}
my_list=[1,2,3]
book=BookInfo.objects.get(id=1)
#定義模板上下文
context={'my_dict':my_dict,'my_list':my_list,'book':book}
return render(request,'booktest/temp_var.html',context)
vim urls.py
from django.conf.urls import url
from booktest import views
urlpatterns = [
url(r'^temp_var$',views.temp_var),#模板變量
]
vim temp_var.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板變量</title>
</head>
<body>
使用字典屬性:{{ my_dict.title }}<br/>
使用列表元素:{{ my_list.1 }}<br/>
使用對象屬性:{{ book.btitle }}<br/>
</body>
</html>
模板代碼段:{% 代碼段 %}
for循環:
{% for i in list %}
列表不為空時執行
{% empty %}
列表為空時執行
{% endfor %}
可以通過{{ forloop.counter }}
得到for循環遍歷到了第幾次
vim urls.py
from django.conf.urls import url
from booktest import views
urlpatterns = [
url(r'^temp_tags$',views.temp_tags),
]
vim views.py
# /temp_tags
def temp_tags(request):
'''模板標簽'''
#1. 查找所有圖書的信息
books=BookInfo.objects.all()
return render(request,'booktest/temp_tags.html',{'books':books})
vim temp_tags.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板標簽</title>
</head>
<body>
<ul>
{% for book in books %}
<li>{{ forlop.counter }}--{{ book.btitle }}</li>
{% endfor %}
</ul>
</body>
</html>
{% if 條件 %}
{% elif 條件 %}
{% else %}
{% endif %}
關系比較操作符:< > <= >= !=
注意:進行比較時,比較操作符兩邊必須有空格
邏輯運算:not and or
vim temp_tags.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板標簽</title>
<style>
.red {
background-color: red;
}
.yellow {
background-color: yellow;
}
.green {
background-color: green;
}
</style>
</head>
<body>
<ul>
{% for book in books %}
{% if book.id <= 2 %}
<li class="red">{{ forloop.counter }}--{{ book.btitle }}</li>
{% elif book.id <= 4 %}
<li class="yellow">{{ forloop.counter }}--{{ book.btitle }}</li>
{% else %}
<li class="green">{{ forloop.counter }}--{{ book.btitle }}</li>
{% endif %}
{% endfor %}
</ul>
</body>
</html>
過濾器用于對模板變量進行操作
date:改變日期的顯示格式
length:求長度。字符串,列表長度
default:設置模板變量的默認值
格式:模板變量|過濾器:參數
自定義過濾器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板過濾器</title>
<style>
.red {
background-color: red;
}
.green {
background-color: green;
}
</style>
</head>
<body>
<ul>
{% for book in books %}
{% if book.id <= 2 %}
<li class="red">{{ book.btitle }}--{{ book.bpub_date|date:'Y年-m月-d日' }}</li>
{% else %}
<li class="green">{{ book.btitle }}--{{ book.bpub_date }}</li>
{% endif %}
{% endfor %}
</ul>
default過濾器:<br/>
{{ content|default:'hello' }}
</body>
</html>
在應用下創建一個包templatetags,包的名字固定,在包下創建一個過濾器文件vim filters.py
#自定義過濾器
#過濾器其實就是python函數
from django.template import Library
#創建一個library類的對象
register=Library()
#自定義的過濾器函數,最少有一個參數,最多有兩個
@register.filter
def mod(num):
'''判斷num是否為偶數'''
return num%2 == 0
@register.filter
def mod_val(num,val):
'''判斷num是否能被val整除'''
return num%val ==0
vim temp_filters.html
<!DOCTYPE html>
<html lang="en">
{% load filters %}
<head>
<meta charset="UTF-8">
<title>模板過濾器</title>
<style>
.red {
background-color: red;
}
.green {
background-color: green;
}
</style>
</head>
<body>
<ul>
{% for book in books %}
{# {% if book.id <= 2 %} #}
{# {% if book.id|mod %} #}
{% if book.id|mod_val:3 %}
<li class="red">{{ book.id }}--{{ book.btitle }}--{{ book.bpub_date|date:'Y年-m月-d日' }}</li>
{% else %}
<li class="green">{{ book.btitle }}--{{ book.bpub_date }}</li>
{% endif %}
{% endfor %}
</ul>
default過濾器:<br/>
{{ content|default:'hello' }}
</body>
</html>
單行注釋:{# 注釋內容 #}
多行注釋:{% comment %}
注釋內容
{% endcomment %}
把所有頁面相同的內容放到父模板文件中,不需要放在塊中,有些位置頁面內容不同,需要在父模板中預留塊。
在父模板里可以定義塊,使用標簽:{% block 塊名 %}
塊中間可以寫內容,也可以不寫{% endblock 塊名 %}
字模板去繼承父模板之后,可以重寫父模板中的某一塊內容
繼承格式:
{% extends 父模板文件路徑 %}
{% block 塊名 %}
{{ block.super }} #獲取父模板中塊的默認內容
重寫的內容
{% endblock 塊名 %}
vim views.py
#/temp_inherit
def temp_inherit(request):
'''模板繼承'''
return render(request,'booktest/child.html')
vim base.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>父模板文件</title>
</head>
<body>
<h2>導航條</h2>
{% block b1 %}
<h2>這是父模板b1塊中</h2>
{% endblock b1 %}
<h2>版權信息</h2>
</body>
</html>
vim child.html
{% extends 'booktest/base.html' %}
{% block b1 %}
{{ block.super }}
<b1>這是子模板b1塊中的內容</b1>
{% endblock b1 %}
vim urls.py
url(r'^temp_inherit$',views.temp_inherit), ##模板繼承
編輯商品詳情信息,數據表中保存的是html內容
在模板上下文中的html標記默認是會被轉義的
< 轉化為& lt;
> 轉換為& gt;
' 轉換為& #39;
" 轉換為& quot;
& 轉換為& amp;
要關閉模板上下文字符串的轉義:可以使用{{ 模板變量|safe }}
也可以使用
{% autoescape off %}
模板語言代碼
{% endautoescape %}
模板硬編碼中的字符串默認不會經過轉義,如果需要轉義,那需要手動進行轉義
vim views.py
def html_escape(request):
'''HTML轉義'''
return render(request,'booktest/html_escape.html',{'content':'<h2>hello</h2>'})
vim urls.py
url(r'^html_escape$',views.html_escape), #HTML轉義
vim html_escap[e.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>html轉義</title>
</head>
<body>
{{ content }}
使用safe過濾器關閉轉義:<br/>
{{ content|safe }}
</br>
模板硬編碼中的字符串不會經過轉義<br/>
{{ test|default:'<h2>hello</h2>' }}<br/>
手動進行轉義:<br/>
{{ test|default:'<h2>hello</h2>' }}
</body>
</html>
首先做一個登錄頁,讓用戶輸入用戶名和密碼進行登錄,登陸成功之后跳轉的修改密碼頁面。在修改密碼頁面輸入新密碼,點擊確認按鈕完成密碼修改
登錄頁需要一個模板文件login.html,修改密碼頁面也需要一個模板文件
change_pwd.html
顯示登錄頁的視圖login,驗證登錄的視圖login_check,顯示發帖頁的視圖change_pwd,處理修改密碼的視圖change_pwd_action
加功能:
vim views.py
def login_required(view_func):
'''登錄判斷裝飾器'''
def wrapper(request,*views_args,**view_kwargs):
#判斷用戶是否登錄
if request.session.has_key('islogin'):
#用戶已登錄,調用對應的視圖
return view_func(request,*views_args,**view_kwargs)
else:
#用戶未登錄,跳轉到登錄頁
return redirect('/login')
return wrapper
def login(request):
'''顯示登錄頁面'''
#判斷用戶是否登錄
if request.session.has_key('islogin'):
return redirect('/index')
else:
#用戶未登錄
#獲取cookie username
if 'username' in request.COOKIES:
#獲取記住的用戶名
username = request.COOKIES['username']
else:
username=''
return render(request,'booktest/login.html',{'username':username})
def login_check(request):
'''登錄校驗視圖'''
username=request.POST.get('username')
password=request.POST.get('password')
remember=request.POST.get('remember')
#2. 進行登錄的校驗
#實際開發:根據用戶和密碼查找數據庫
#模擬:smart 123
if username=='smart' and password=='123':
#用戶名密碼正確,跳轉到首頁
response=redirect('/index')
#判斷是否需要記住用戶名
if remember == 'on':
#設置cookie username,過期時間為一周
response.set_cookie('username',username,max_age=7*24*3600)
#記住用戶登錄狀態
#只有session中有islogin,就認為用戶已登錄
request.session['islogin']=True
#記住登錄的用戶名
request.session['username']=username
return response
else:
#用戶名或密碼錯誤,跳轉到登錄頁面
request.session['username']=username
return redirect('/change_pwd')
# /change_pwd
@login_required
def change_pwd(request):
'''顯示修改密碼頁面'''
return render(request,'booktest/change_pwd.html')
# /change_pwd_action
@login_required
def change_pwd_action(request):
'''模擬修改密碼處理'''
# 1.獲取新密碼
pwd=request.POST.get('pwd')
#獲取用戶名
username=request.session.get('username')
#2.實際開發的時候:修改對應數據庫的內容
#3.返回一個應答
return HttpResponse('%s修改密碼為:%s' %(username,pwd))
vim urls.py
url(r'^login$',views.login), #顯示登錄頁面
url(r'^login_check$',views.login_check), #進行登錄校驗
url(r'^change_pwd$',views.change_pwd), #修改密碼頁面顯示
url(r'^change_pwd_action$',views.change_pwd_action), #修改密碼處理
vim login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄頁面</title>
</head>
<body>
<form method="post" action="/login_check">
用戶名:<input type="text" name="username" value="{{ username }}"><br/>
密碼:<input type="password" name="password"><br/>
<input type="checkbox" name="remember">記住用戶名<br/>
<input type="submit" value="登錄">
</form>
</body>
</html>
vim change_pwd.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>修改密碼界面</title>
</head>
<body>
<form method="post" action="/change_pwd_action">
新密碼:<input type="password" name="pwd">
<input type="submit" value="確認修改">
</form>
</body>
</html>
防御原理:
vim views.py
def login_check(request):
'''登錄校驗視圖'''
username=request.POST.get('username')
password=request.POST.get('password')
remember=request.POST.get('remember')
#獲取用戶輸入驗證碼
vcode1=request.POST.get('vcode')
#獲取session中保存的驗證碼
vcode2=request.session.get('verifycode')
#進行驗證碼校驗
if vcode1 != vcode2:
#驗證碼錯誤
return redirect('/login')
#2. 進行登錄的校驗
#實際開發:根據用戶和密碼查找數據庫
#模擬:smart 123
if username=='smart' and password=='123':
#用戶名密碼正確,跳轉到首頁
response=redirect('/index')
#判斷是否需要記住用戶名
...
#/驗證碼
from PIL import Image,ImageDraw,ImageFont
from django.utils.six import BytesIO
def verify_code(request):
#引入隨機函數模塊
import random
#定義變量,用于畫面的背景色、寬、高
bgcolor=(random.randrange(20,100),random.randrange(20,100),255)
width=100
height=25
#構建畫面圖像
im=Image.new('RGB',(width,height),bgcolor)
#創建畫筆對象
draw=ImageDraw.Draw(im)
#調用畫筆的point()函數繪制噪點
for i in range(0,100):
xy=(random.randrange(0,width),random.randrange(0,height))
fill=(random.randrange(0,255),255,random.randrange(0,255))
draw.point(xy,fill=fill)
#定義驗證碼的備選值
str1='ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
#隨機選取4個值作為驗證碼
rand_str=''
for i in range(0,4):
rand_str+=str1[random.randrange(0,len(str1))]
#構造字體對象
font=ImageFont.truetype('/usr/share/fonts/gnu-free/FreeMonoBold.ttf',23)
#構造字體的顏色
fontcolor=(255,random.randrange(0,255),random.randrange(0,255))
#繪制四個字
draw.text((5,2),rand_str[0],font=font,fill=fontcolor)
draw.text((25,2),rand_str[1],font=font,fill=fontcolor)
draw.text((50, 2), rand_str[2], font=font, fill=fontcolor)
draw.text((75, 2), rand_str[3], font=font, fill=fontcolor)
#釋放畫筆
del draw
#存入session,用于做進一步驗證
request.session['verifycode']=rand_str
#內存文件操作
buf=BytesIO()
#將圖片保存在內存中,文件類型是png
im.save(buf,'png')
#將內存中的圖片數據返回給客戶端,mime類型為圖片png
return HttpResponse(buf.getvalue(),'image/png')
vim login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄頁面</title>
</head>
<body>
<form method="post" action="/login_check">
{% csrf_token %}
用戶名:<input type="text" name="username" value="{{ username }}"><br/>
密碼:<input type="password" name="password"><br/>
<input type="checkbox" name="remember">記住用戶名<br/>
<img src="/verify_code"><input type="text" name="vcode"><br/>
<input type="submit" value="登錄">
</form>
</body>
</html>
當某一個url配置的地址發生變化時,頁面上使用反向解析生成地址的位置不需要發生變化
根據url正則表達式的配置動態的生成url
vim booktest/views.py
url(r'^url_reverse$',viewa.url_reverse), #反向解析頁面
vim models.py
from django.db import models
# Create your models here.
class BookInfo(models.Model):
'''圖書模型類'''
#圖書名稱
btitle=models.CharField(max_length=20)
#出版日期
bpub_date=models.DateField()
#閱讀量
bread=models.IntegerField(default=0)
#評論量
bcomment=models.IntegerField(default=0)
#刪除標記
isdelete=models.BooleanField(default=False)
class HeroInfo(models.Model):
'''英雄人物模型類'''
#英雄名
hname=models.CharField(max_length=20)
#性別
hgender=models.BooleanField(default=False)
#備注
hcomment=models.CharField(max_length=200)
#關系屬性
hbook=models.ForeignKey('BookInfo',on_delete=models.CASCADE,)
# 刪除標記
isdelete=models.BooleanField(default=False)
執行遷移文件生成表
python manage.py makemigrations
python manage.py migrate
往數據表里插入數據
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);
insert into booktest_heroinfo(hname,hgender,hbook_id,hcomment,isdelete) valu s 掌0) ('郭靖',1,1,'降龍十八掌',0), ('黃蓉',0,1,'打狗棍法',0), ('黃藥師',1,1,'彈指神 姐姐 ('歐陽鋒',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,'華.劍Query OK, 17 rows affected (0.00 sec)), ('胡斐',1,4,'胡家刀法',0), ('苗春蘭',0,4,'黃衣Records: 17 Duplicates: 0 Warnings: 00,4,'六合拳',0);
vim index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>圖書信息</title>
</head>
<body>
<a href="/create">新增</a>
<ul>
{% for book in books %}
<li>{{ book.btitle }}--<a href="/delete{{ book.id }}">刪除</a></li>
{% endfor %}
</ul>
</body>
</html>
vim booktest/views.py
from django.shortcuts import render,redirect
from booktest.models import BookInfo
from datetime import date
from django.http import HttpResponse,HttpResponseRedirect
# Create your views here.
def index(request):
'''顯示圖書信息'''
#1. 查詢出所有圖書的信息
books=BookInfo.objects.all()
#2.使用模板
return render(request,'booktest/index.html',{'books':books})
def create(request):
'''新增一本圖書'''
#1.創建BookInfo對象
b=BookInfo()
b.btitle='流星蝴蝶劍'
b.bpub_date=date(1990,1,1)
#2.保存進數據庫
b.save()
#3.返回應答,讓瀏覽器再訪問/index
return HttpResponse('ok')
#return HttpResponseRedirect('/index')
def delete(request,bid):
'''刪除點擊的圖書'''
#1.通過bid獲取圖書對象
book=BookInfo.objects.get(id=bid)
#2.刪除
book.delete()
#3.重定向,讓瀏覽器訪問/index
#return HttpResponseRedirect('/index')
return redirect('/index')
vim test2/urls.py
from django.contrib import admin
#from django.urls import path
from django.conf.urls import include,url
urlpatterns = [
url(r'^admin/',admin.site.urls),#配置項
url(r'^',include('booktest.urls')) #包含test1應用中的urls文件
]
vim booktest/urls.py
from django.conf.urls import url
from booktest import views
urlpatterns=[
url(r'^index$',views.index), #圖書信息頁面
url(r'^create$',views.create), #添加圖書信息
url(r'^delete(\d+)$',views.delete), #刪除點擊的圖書
]
修改mysql的日志文件:
讓其產生mysql.log,即是mysql的日志文件,里面記錄的對mysql數據庫的操作記錄
general_log=1 general_log_file= /usr/local/mysql/data/mysql.log
,然后保存vi /etc/my.cnf
mysql.server start
tail /usr/local/mysql/data/mysql.log
通過模型類.objects屬性可以調用如下函數,實現對模型類對應的數據表的查詢
函數名 | 功能 | 返回值 | 說明 |
---|---|---|---|
get | 返回表中滿足條件的一條且只能有一條數據 | 返回值是一個模型類對象 | 參數中寫查詢條件 1.如果查到多條數據,則拋異常multipleobjectreturned。2.查詢不到數據,則拋異常:doesnotexist |
all | 返回模型類對應表格中的所有數據 | 返回值是queryset類型 | 查詢集 |
filter | 返回滿足條件的數據 | 返回值是queryset類型 | 參數寫查詢條件 |
exclude | 返回不滿足條件的數據 | 返回值是queryset類型 | 參數寫查詢條件 |
order_by | 對查詢結果進行排序 | 返回值是queryset類型 | 參數中寫根據哪些字段進行排序 |
作用:用于查詢時條件之間的邏輯關系。mot and or,可以對Q對象進行&|~操作
使用之前需要先導入:from Django.db.models import Q
例:查詢id大于3且閱讀量大于30的圖書的信息BookInfo.objects.filter(id__gt=3,bread__gt=30)
BookInfo.objects.filter(Q(id__gt=3)&Q(bread__gt=30))
例:查詢id大于3或者閱讀量大于30的圖書的信息BookInfo.objects.filter(Q(id__gt=3)|Q(bread__gt=30))
例:查詢id不等于3圖書的信息BookInfo.objects.filter(~Q(id=3))
作用:用于類屬性之間的比較
使用之前需要先導入:from django.db.models import F
例:查詢圖書閱讀量大于評論量圖書的信息BookInfo.objects.filter(bread__gt=F('bcomment'))
例:查詢圖書閱讀量大于2倍評論量圖書信息BookInfo.objects.filter(bread__gt=F('bcomment')*2)
作用:對查詢結果進行聚合操作
sum count avg max min
aggregate:調用這個函數來使用聚合。返回值是一個字典。
使用前需先導入聚合類:from django.db.models import Sum,Count,Max,Min,Avg
例:查詢所有圖書的數目
select count(*) from booktest_bookinfo;
BookInfo.objects.all().aggregate(Count('id'))
BookInfo.objects.aggregate(Count('id'))
例:查詢所有圖書閱讀量的總和BookInfo.objects.aggregate(Sum('bread'))
all,filter,exclude,order_by調用這些函數會產生一個查詢集
QuerySet類對象可以繼續調用上面的所有函數
可以對一個查詢集進行取下標或者切片操作來限制查詢集的結果
對一個查詢集進行切片操作會產生一個新的查詢集,下標不允許為負數。
取出查詢集第一條數據的兩種方式:
方式 | 說明 |
---|---|
b[0] | 如果b[0]不存在,會拋出IndexError異常 |
b[0:1].get() | 如果b[0:1].get()不存在,會拋出DoesNotExist異常 |
models.ForeignKey()
定義多的類中
models.ManyToManyField()
定義在哪個類中都可以models.OneToOneField
定義在哪個類中都可以在一對多關系中,一對應的類我們把他叫做一類,多對應的類我們把它叫做多類,我們把多類中定義的建立關聯的類屬性叫做關聯屬性。
例:查詢id為1的圖書關聯的英雄的信息。
b=BookInfo.objects.get(id=1)
b.heroinfo_set.all()
通過模型類查詢:HeroInfo.objects.filter(hbook__id=1)
例:查詢id為1的英雄關聯的圖書信息
h=HeroInfo.objects.get(id=1)
h.hbook()
通過模型類查詢:BookInfo.objects.filter(heroinfo__id=1)
自關聯是一種特殊的一對多的關系
BookInfo.objects.all()->ojects是一個什么東西呢?
答:
class BookInfoManager(models.Manager):
'''圖書模型管理器類'''
# 1.改變查詢的結果集
def all(self):
#1.調用父類的all,獲取所有數據
books=super().all() #QuerySet
#2. 對數據進行過濾
books=books.filter(isDelete=False)
#3.返回books
return books
#2.封裝函數:操作模型類對應的數據表(增刪改查)
def create_book(self,btitle,bpub_date):
#1.創建一個圖書對象
model_class=self.model
book=model_class()
#book=BookInfo()
book.btitle=btitle
book.bpub_date=bpub_date
#2.保存進數據庫
book.save()
#3.返回book
return book
class BookInfo(models.Model):
class Meta:
db_table='bookinfo'
在網頁使用的css文件,js文件和圖片叫做靜態文件
vim settings.py
#設置訪問靜態文件對應的url地址
STATIC_URL = '/static/'
#設置靜態文件存放的物理目錄
STATICFILES_DIRS=[os.path.join(BASE_DIR,'static')]
vim static_test.html
<!DOCTYPE html>
{% load staticfiles %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>靜態文件</title>
</head>
<body>
<img src="/static/images/mm.jpg"><br/>
動態獲取STATIC_URL,拼接靜態文件路徑:<br/>
<img src="{% static 'images/mm.jpg' %}">
</body>
</html>
vim views.py
from django.shortcuts import render
from django.conf import settings
# Create your views here.
# /static_test
def static_test(request):
'''靜態文件'''
print(settings.STATICFILES_FINDERS)
return render(request,'booktest/static_test.html')
vim urls.py
from django.conf.urls import url
from booktest import views
urlpatterns = [
url(r'^static_test$',views.static_test), #靜態文件
]
STATICFILES_FINDERS=('django.contrib.staticfiles.finders.FileSystemFinder','django.contrib.staticfiles.finders.AppDirectoriesFinder')
中間件函數是Django框架給我們預留的函數接口,讓我們可以干預請求和應答的過程
使用request對象的meta屬性:request.META['REMOTE_ADDR']
vim booktest/middleware.py
如果注冊的多個中間件類中包含process_exception函數的時候,調用的順序跟注冊的順序是相反的
vim booktest/middleware.py
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin
class BlockedIPSMiddleware(object):
EXCLUDE_IPS=['223.71.207.106']
def process_view(self,request,view_func,*view_arg,**view_kwargs):
'''視圖函數調用之前會調用'''
user_ip=request.META['REMOTE_ADDR']
if user_ip in BlockedIPSMiddleware.EXCLUDE_IPS:
return HttpResponse('<h2>Forbidden</h2>')
vim settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'booktest.middleware.BlockedIPSMiddleware', #注冊中間件類
]
#設置上傳文件的保存目錄
MEDIA_ROOT=os.path.join(BASE_DIR,'static/media')
vim models.py
from django.db import models
# Create your models here.
class PicTest(models.Model):
'''上傳圖片''' goods_pic=models.ImageField(upload_to='booktest')
python manage.py makimigrations
python manage.py migrate
vim admin.py
from django.contrib import admin
from booktest.models import PicTest
admin.site.register(PicTest)
vim upload_pic.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上傳圖片</title>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="upload_handle">
{% csrf_token %}
<input type="file" name="pic"><br/>
<input type="submit" value="上傳">
</form>
</body>
</html>
vim views.py
from booktest.models import PicTest
def show_upload(request):
'''顯示上傳圖片頁面'''
return render(request,'booktest/upload_pic.html')
def upload_handle(request):
'''上傳圖片處理'''
# 1.獲取上傳的圖片
pic =request.FILES['pic']
#print (pic.name)
#2.創建一個文件
save_path= '%s/booktest/%s' %(settings.MEDIA_ROOT,pic.name)
with open(save_path,'wb') as f:
#3.獲取上傳文件的內容并寫到創建的文件中
for content in pic.chunks():
f.write(content)
#4. 在數據庫中保存上傳記錄
PicTest.objects.create(goods_pic='booktest/%s' %pic.name)
#5.返回
return HttpResponse('ok')
上傳文件不大于2.5M,文件放在內存中
上傳文件大于2.5M,文件內容寫到一個臨時文件中
查詢出所有省級地區的信息,顯示在頁面上。AreaInfo.objects.filter(aparent_isnull)
from django.core.paginator import Paginator
paginator=Paginator(areas,10) #按每頁10條數據進行分頁
Paginator類對象的屬性
屬性名 | 說明 |
---|---|
num_pages | 返回分頁之后的總頁數 |
page_range | 返回分頁頁碼的列表 |
Paginator
方法名 | 說明 |
---|---|
page(self,number) | 返回第number頁的page類實例對象 |
Page類對象的屬性
屬性名 | 說明 |
---|---|
number | 返回當前頁的頁碼 |
object_list | 返回包含當前頁的數據的查詢 |
paginator | 返回對應的Paginator類對象 |
Page類對象的方法
屬性名 | 說明 |
---|---|
has_previous | 判斷當前頁是否有前一頁 |
has_next | 判斷當前頁是否有下一頁 |
previous_page_number | 返回前一頁的頁碼 |
next_page_number | 返回下一頁的頁碼 |
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。