pip list pip freeze
pip install django==1.8.2
import django django.get_version()
在一個項目中能夠建立一到多個應用,每一個應用進行一種業務處理 建立應用的命令:javascript
python manage.py startapp booktest
定義模型類css
from django.db import models class BookInfo(models.Model): btitle = models.CharField(max_length=20) bpub_date = models.DateTimeField() def _ _str_ _(self): return "%d" % self.pk class HeroInfo(models.Model): hname = models.CharField(max_length=20) hgender = models.BooleanField() hcontent = models.CharField(max_length=100) hBook = models.ForeignKey('BookInfo') def _ _str_ _(self): return "%d" % self.pk
生成數據表html
python manage.py makemigrations
python manage.py migrate
測試數據操做java
python manage.py shell
from booktest.models import BookInfo,HeroInfo from django.utils import timezone from datetime import *
BookInfo.objects.all()
b = BookInfo() b.btitle="射鵰英雄傳" b.bpub_date=datetime(year=1990,month=1,day=10) b.save()
b=BookInfo.objects.get(pk=1)
b b.id b.btitle
b.btitle=u"天龍八部" b.save()
b.delete()
關聯對象的操做python
h=HeroInfo() h.htitle=u'郭靖' h.hgender=True h.hcontent=u'降龍十八掌' h.hBook=b h.save()
b.heroinfo_set.all()
h=b.heroinfo_set.create(htitle=u'黃蓉',hgender=False,hcontent=u'打狗棍法') h
python manage.py runserver ip:port
python manage.py runserver 8080
使用django的管理mysql
python manage.py createsuperuser,按提示輸入用戶名、郵箱、密碼
管理界面本地化jquery
LANGUAGE_CODE = 'zh-Hans' TIME_ZONE = 'Asia/Shanghai'
向admin註冊booktest的模型nginx
from django.contrib import admin from models import BookInfo admin.site.register(BookInfo)
自定義管理頁面git
class QuestionAdmin(admin.ModelAdmin): ... admin.site.register(Question, QuestionAdmin)
列表頁屬性程序員
list_display = ['pk', 'btitle', 'bpub_date']
list_filter = ['btitle']
search_fields = ['btitle']
list_per_page = 10
添加、修改頁屬性
fields = ['bpub_date', 'btitle']
fieldsets = [ ('basic',{'fields': ['btitle']}), ('more', {'fields': ['bpub_date']}), ]
關聯對象
對於HeroInfo模型類,有兩種註冊方式
按照BookInfor的註冊方式完成HeroInfo的註冊
from django.contrib import admin from models import BookInfo,HeroInfo class HeroInfoInline(admin.StackedInline): model = HeroInfo extra = 2 class BookInfoAdmin(admin.ModelAdmin): inlines = [HeroInfoInline] admin.site.register(BookInfo, BookInfoAdmin)
class HeroInfoInline(admin.TabularInline)
布爾值的顯示
def gender(self): if self.hgender: return '男' else: return '女' gender.short_description = '性別'
class HeroInfoAdmin(admin.ModelAdmin): list_display = ['id', 'hname', 'gender', 'hcontent']
#coding:utf-8 from django.http import HttpResponse def index(request): return HttpResponse("index") def detail(request,id): return HttpResponse("detail %s" % id)
url(r'^', include('booktest.urls')),
from django.conf.urls import url from . import views urlpatterns = [ url(r'^$', views.index), url(r'^([0-9]+)/$', views.detail), ]
'DIRS': [os.path.join(BASE_DIR, 'templates')],
{{輸出值,能夠是變量,也能夠是對象.屬性}} {%執行代碼段%}
定義index.html模板
<!DOCTYPE html> <html> <head> <title>首頁</title> </head> <body> <h1>圖書列表</h1> <ul> {%for book in booklist%} <li> <a href="{{book.id}}"> {{book.btitle}} </a> </li> {%endfor%} </ul> </body> </html>
定義detail.html模板
<!DOCTYPE html> <html> <head> <title>詳細頁</title> </head> <body> <h1>{{book.btitle}}</h1> <ul> {%for hero in book.heroinfo_set.all%} <li>{{hero.hname}}---{{hero.hcontent}}</li> {%endfor%} </ul> </body> </html>
from django.http import HttpResponse from django.template import RequestContext, loader from models import BookInfo def index(request): booklist = BookInfo.objects.all() template = loader.get_template('booktest/index.html') context = RequestContext(request, {'booklist': booklist}) return HttpResponse(template.render(context)) def detail(reqeust, id): book = BookInfo.objects.get(pk=id) template = loader.get_template('booktest/detail.html') context = RequestContext(reqeust, {'book': book}) return HttpResponse(template.render(context))
<a href="{{book.id}}">
url(r'^book/([0-9]+)/$', views.detail),
url(r'^admin/', include(admin.site.urls, namespace='booktest')),
url(r'^book/([0-9]+)/$', views.detail, name="detail"),
<a href="{%url 'booktest:detail' book.id%}">
from django.shortcuts import render from models import BookInfo def index(reqeust): booklist = BookInfo.objects.all() return render(reqeust, 'booktest/index.html', {'booklist': booklist}) def detail(reqeust, id): book = BookInfo.objects.get(pk=id) return render(reqeust, 'booktest/detail.html', {'book': book})
pip install mysql-python
create databases test2 charset=utf8
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'test2', 'USER': '用戶名', 'PASSWORD': '密碼', 'HOST': '數據庫服務器ip,本地可使用localhost', 'PORT': '端口,默認爲3306', } }
python manage.py inspectdb > booktest/models.py
字段類型
字段選項
關係
bookinfo.heroinfo_set
heroinfo.bookinfo
heroinfo.book_id
<app_name>_<model_name>
class BookInfo(models.Model): ... class Meta(): ordering = ['id']
class BookInfo(models.Model): ... class Meta(): ordering = ['-id']
class BookInfo(models.Model): btitle = models.CharField(max_length=20) bpub_date = models.DateTimeField() bread = models.IntegerField(default=0) bcommet = models.IntegerField(default=0) isDelete = models.BooleanField(default=False)
class HeroInfo(models.Model): hname = models.CharField(max_length=20) hgender = models.BooleanField(default=True) isDelete = models.BooleanField(default=False) hcontent = models.CharField(max_length=100) hbook = models.ForeignKey('BookInfo')
insert into booktest_bookinfo(btitle,bpub_date,bread,bcommet,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,hcontent,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)
class BookInfo(models.Model): ... books = models.Manager()
管理器Manager
class BookInfoManager(models.Manager): def get_queryset(self): return super(BookInfoManager, self).get_queryset().filter(isDelete=False) class BookInfo(models.Model): ... books = BookInfoManager()
class BookInfo(models.Model): ... @classmethod def create(cls, title, pub_date): book = cls(btitle=title, bpub_date=pub_date) book.bread=0 book.bcommet=0 book.isDelete = False return book 引入時間包:from datetime import * 調用:book=BookInfo.create("hello",datetime(1980,10,11)); 保存:book.save()
class BookInfoManager(models.Manager): def create_book(self, title, pub_date): book = self.model() book.btitle = title book.bpub_date = pub_date book.bread=0 book.bcommet=0 book.isDelete = False return book class BookInfo(models.Model): ... books = BookInfoManager() 調用:book=BookInfo.books.create_book("abc",datetime(1980,1,1)) 保存:book.save()
class BookInfoManager(models.Manager): def create_book(self, title, pub_date): book = self.create(btitle = title,bpub_date = pub_date,bread=0,bcommet=0,isDelete = False) return book class BookInfo(models.Model): ... books = BookInfoManager() 調用:book=Book.books.create_book("abc",datetime(1980,1,1)) 查看:book.pk
filter(鍵1=值1,鍵2=值2) 等價於 filter(鍵1=值1).filter(鍵2=值2)
限制查詢集
查詢集的緩存
print([e.title for e in Entry.objects.all()]) print([e.title for e in Entry.objects.all()])
querylist=Entry.objects.all() print([e.title for e in querylist]) print([e.title for e in querylist])
比較運算符
filter(isDelete=False)
exclude(btitle__contains='傳')
exclude(btitle__endswith='傳')
filter(btitle__isnull=False)
filter(pk__in=[1, 2, 3, 4, 5])
filter(id__gt=3)
filter(bpub_date__year=1980) filter(bpub_date__gt=date(1980, 12, 31))
filter(heroinfo_ _hcontent_ _contains='八')
filter(pk__lt=6)
聚合函數
from django.db.models import Max maxDate = list.aggregate(Max('bpub_date'))
count = list.count()
F對象
list.filter(bread__gte=F('bcommet'))
list.filter(bread__gte=F('bcommet') * 2)
list.filter(isDelete=F('heroinfo__isDelete'))
list.filter(bpub_date__lt=F('bpub_date') + timedelta(days=1))
Q對象
from django.db.models import Q list.filter(Q(pk_ _lt=6))
list.filter(pk_ _lt=6).filter(bcommet_ _gt=10) list.filter(Q(pk_ _lt=6) | Q(bcommet_ _gt=10))
list.filter(~Q(pk__lt=6))
class AreaInfo(models.Model): atitle = models.CharField(max_length=20) aParent = models.ForeignKey('self', null=True, blank=True)
上級對象:area.aParent 下級對象:area.areainfo_set.all()
from models import AreaInfo def area(request): area = AreaInfo.objects.get(pk=130100) return render(request, 'booktest/area.html', {'area': area})
<!DOCTYPE html> <html> <head> <title>地區</title> </head> <body> 當前地區:{{area.atitle}} <hr/> 上級地區:{{area.aParent.atitle}} <hr/> 下級地區: <ul> { %for a in area.areainfo_set.all%} <li>{{a.atitle}}</li> { %endfor%} </ul> </body> </html>
urlpatterns = [ url(r'^area/$', views.area, name='area') ]
http://www.itcast.cn/python/1/?i=1&p=new,只匹配「/python/1/」部分
url(r'^([0-9]+)/$', views.detail, name='detail'),
url(r'^(?P<id>[0-9]+)/$', views.detail, name='detail'),
包含其它的URLconfs
from django.conf.urls import include, url urlpatterns = [ url(r'^', include('booktest.urls', namespace='booktest')), ]
請求http://www.itcast.cn/booktest/1/ 在sesstings.py中的配置: url(r'^booktest/', include('booktest.urls', namespace='booktest')), 在booktest應用urls.py中的配置 url(r'^([0-9]+)/$', views.detail, name='detail'), 匹配部分是:/booktest/1/ 匹配過程:在settings.py中與「booktest/」成功,再用「1/」與booktest應用的urls匹配
URL的反向解析
新建views1.py #coding:utf-8 from django.http import HttpResponse def index(request): return HttpResponse("你好") 在urls.py中修改配置 from . import views1 url(r'^$', views1.index, name='index'),
404 (page not found) 視圖
<!DOCTYPE html> <html> <head> <title></title> </head> <body> 找不到了 <hr/> {{request_path}} </body> </html>
DEBUG = False ALLOWED_HOSTS = ['*', ]
http://127.0.0.1:8000/test/
500 (server error) 視圖
400 (bad request) 視圖
屬性
方法
dict.get('鍵',default) 或簡寫爲 dict['鍵']
dict.getlist('鍵',default)
def getTest1(request): return render(request,'booktest/getTest1.html') def getTest2(request): return render(request,'booktest/getTest2.html') def getTest3(request): return render(request,'booktest/getTest3.html')
url(r'^getTest1/$', views.getTest1), url(r'^getTest2/$', views.getTest2), url(r'^getTest3/$', views.getTest3),
<html> <head> <title>Title</title> </head> <body> 連接1:一個鍵傳遞一個值 <a href="/getTest2/?a=1&b=2">gettest2</a><br> 連接2:一個鍵傳遞多個值 <a href="/getTest3/?a=1&a=2&b=3">gettest3</a> </body> </html>
def getTest2(request): a=request.GET['a'] b=request.GET['b'] context={'a':a,'b':b} return render(request,'booktest/getTest2.html',context)
<html> <head> <title>Title</title> </head> <body> a:{{ a }}<br> b:{{ b }} </body> </html>
def getTest3(request): a=request.GET.getlist('a') b=request.GET['b'] context={'a':a,'b':b} return render(request,'booktest/getTest3.html',context)
<html> <head> <title>Title</title> </head> <body> a:{% for item in a %} {{ item }} {% endfor %} <br> b:{{ b }} </body> </html>
def postTest1(request): return render(request,'booktest/postTest1.html')
url(r'^postTest1$',views.postTest1)
<html> <head> <title>Title</title> </head> <body> <form method="post" action="/postTest2/"> 姓名:<input type="text" name="uname"/><br> 密碼:<input type="password" name="upwd"/><br> 性別:<input type="radio" name="ugender" value="1"/>男 <input type="radio" name="ugender" value="0"/>女<br> 愛好:<input type="checkbox" name="uhobby" value="胸口碎大石"/>胸口碎大石 <input type="checkbox" name="uhobby" value="跳樓"/>跳樓 <input type="checkbox" name="uhobby" value="喝酒"/>喝酒 <input type="checkbox" name="uhobby" value="登山"/>登山<br> <input type="submit" value="提交"/> </form> </body> </html>
def postTest2(request): uname=request.POST['uname'] upwd=request.POST['upwd'] ugender=request.POST['ugender'] uhobby=request.POST.getlist('uhobby') context={'uname':uname,'upwd':upwd,'ugender':ugender,'uhobby':uhobby} return render(request,'booktest/postTest2.html',context)
url(r'^postTest2$',views.postTest2)
<html> <head> <title>Title</title> </head> <body> {{ uname }}<br> {{ upwd }}<br> {{ ugender }}<br> {{ uhobby }} </body> </html>
#coding=utf-8 from django.http import HttpResponse def index(request): return HttpResponse('你好')
from django.http import HttpResponse from django.template import RequestContext, loader def index(request): t1 = loader.get_template('polls/index.html') context = RequestContext(request, {'h1': 'hello'}) return HttpResponse(t1.render(context))
屬性
方法
from django.http import HttpResponse from datetime import * def index(request): response = HttpResponse() if request.COOKIES.has_key('h1'): response.write('<h1>' + request.COOKIES['h1'] + '</h1>') response.set_cookie('h1', '你好', 120) # response.set_cookie('h1', '你好', None, datetime(2016, 10, 31)) return response
子類HttpResponseRedirect
在views1.py中 from django.http import HttpResponse,HttpResponseRedirect def index(request): return HttpResponseRedirect('js/') def index2(request,id): return HttpResponse(id) 在應用的urls.py中增長一個url對象 url(r'^([0-9]+)/$', views1.index2, name='index2'),
from django.core.urlresolvers import reverse def index(request): return HttpResponseRedirect(reverse('booktest:index2', args=(1,)))
子類JsonResponse
from django.http import JsonResponse def index2(requeset): return JsonResponse({'list': 'abc'})
render
from django.shortcuts import render def index(request): return render(request, 'booktest/index.html', {'h1': 'hello'})
重定向
from django.shortcuts import redirect from django.core.urlresolvers import reverse def index(request): return redirect(reverse('booktest:index2'))
獲得對象或返回404
from django.shortcuts import * def detail(request, id): try: book = get_object_or_404(BookInfo, pk=id) except BookInfo.MultipleObjectsReturned: book = None return render(request, 'booktest/detail.html', {'book': book}) 將settings.py中的DEBUG改成False 將請求地址輸入2和100查看效果
獲得列表或返回404
from django.shortcuts import * def index(request): # list = get_list_or_404(BookInfo, pk__lt=1) list = get_list_or_404(BookInfo, pk__lt=6) return render(request, 'booktest/index.html', {'list': list}) 將settings.py中的DEBUG改成False
啓用session
項INSTALLED_APPS列表中添加: 'django.contrib.sessions', 項MIDDLEWARE_CLASSES列表中添加: 'django.contrib.sessions.middleware.SessionMiddleware',
使用session
用戶登陸示例
from django.shortcuts import render, redirect from django.core.urlresolvers import reverse def index(request): uname = request.session.get('uname') return render(request, 'booktest/index.html', {'uname': uname}) def login(request): return render(request, 'booktest/login.html') def login_handle(request): request.session['uname'] = request.POST['uname'] return redirect(reverse('main:index')) def logout(request): # request.session['uname'] = None # del request.session['uname'] # request.session.clear() request.session.flush() return redirect(reverse('main:index'))
主url: from django.conf.urls import include, url urlpatterns = [ url(r'^', include('booktest.urls', namespace='main')) ] 應用url: from django.conf.urls import url from . import views urlpatterns = [ url(r'^$', views.index, name='index'), url(r'login/$', views.login, name='login'), url(r'login_handle/$', views.login_handle, name='login_handle'), url(r'logout/$', views.logout, name='logout') ]
<!DOCTYPE html> <html> <head> <title>首頁</title> </head> <body> 你好:{{uname}} <hr/> <a href="{%url 'main:login'%}">登陸</a> <hr/> <a href="{%url 'main:logout'%}">退出</a> </body> </html>
<!DOCTYPE html> <html> <head> <title>登陸</title> </head> <body> <form method="post" action="/login_handle/"> <input type="text" name="uname"/> <input type="submit" value="登陸"/> </form> </body> </html>
會話過時時間
def login_handle(request): request.session['uname'] = request.POST['uname'] # request.session.set_expiry(10) # request.session.set_expiry(timedelta(days=5)) # request.session.set_expiry(0) # request.session.set_expiry(None) return redirect(reverse('main:index'))
存儲session
SESSION_ENGINE='django.contrib.sessions.backends.db'
SESSION_ENGINE='django.contrib.sessions.backends.cache'
SESSION_ENGINE='django.contrib.sessions.backends.cached_db'
使用Redis緩存session
pip install django-redis-sessions
SESSION_ENGINE = 'redis_sessions.session' SESSION_REDIS_HOST = 'localhost' SESSION_REDIS_PORT = 6379 SESSION_REDIS_DB = 0 SESSION_REDIS_PASSWORD = '' SESSION_REDIS_PREFIX = 'session'
啓動:sudo redis-server /etc/redis/redis.conf 中止:sudo redis-server stop 重啓:sudo redis-server restart redis-cli:使用客戶端鏈接服務器 keys *:查看全部的鍵 get name:獲取指定鍵的值 del name:刪除指定名稱的鍵
DIRS=[os.path.join(BASE_DIR,"templates")]
模板處理
loader.get_template(template_name),返回一個Template對象
Template對象的render(RequestContext)方法,使用context渲染模板
from django.template import loader, RequestContext from django.http import HttpResponse def index(request): tem = loader.get_template('temtest/index.html') context = RequestContext(request, {}) return HttpResponse(tem.render(context))
快捷函數
from django.shortcuts import render def index(request): return render(request, 'temtest/index.html')
變量
{{ variable }}
在模板中調用對象的方法
from django.db import models class HeroInfo(models.Model): ... def showName(self): return self.hname
from django.shortcuts import render from models import * def index(request): hero = HeroInfo(hname='abc') context = {'hero': hero} return render(request, 'temtest/detail.html', context)
{{hero.showName}}
標籤
{ %for ... in ...%} 循環邏輯 {{forloop.counter}}表示當前是第幾回循環 { %empty%} 給出的列表爲或列表不存在時,執行此處 { %endfor%}
{ %if ...%} 邏輯1 { %elif ...%} 邏輯2 { %else%} 邏輯3 { %endif%}
{ % comment % } 多行註釋 { % endcomment % }
{ %include "foo/bar.html" % }
{ % url 'name' p1 p2 %}
{ % csrf_token %}
過濾器
if list1|length > 1
name|lower|upper
list|join:", "
value|default:"什麼也沒有"
value|date:'Y-m-d'
註釋
{#...#}
{# { % if foo % }bar{ % else % } #}
示例
{ %block block_name%} 這裏能夠定義默認值 若是不定義默認值,則表示空字符串 { %endblock%}
{ % extends "base.html" %}
{ %block block_name%} 實際填充內容 { %endblock%}
說明
{ % block block_name %} 區域內容 { % endblock block_name %}
1.建立根級模板
<!DOCTYPE html> <html> <head> <title>{%block title%}{%endblock%} 水果超市</title> </head> <body> top--{{logo}} <hr/> {%block left%}{%endblock%} {%block content%}{%endblock%} <hr/> bottom </body> </html>
2.建立分支模版
{%extends 'temtest/base.html'%} {%block title%}商品{%endblock%} {%block left%} <h1>goods left</h1> {%endblock%}
{%extends 'temtest/base.html'%} {%block title%}用戶中心{%endblock%} {%block left%} <font color='blue'>user left</font> {%endblock%}
{%extends 'temtest/base.html'%} {%block content%} 首頁內容 {%endblock content%}
3.爲具體頁面建立模板,繼承自分支模板
{%extends 'temtest/base_goods.html'%} {%block content%} 商品正文列表 {%endblock content%}
{%extends 'temtest/base_user.html'%} {%block content%} 用戶密碼修改 {%endblock content%}
4.視圖調用具體頁面,並傳遞模板中須要的數據
logo='welcome to itcast' def index(request): return render(request, 'temtest/index.html', {'logo': logo})
def goodslist(request): return render(request, 'temtest/goodslist.html', {'logo': logo})
def userpwd(request): return render(request, 'temtest/userpwd.html', {'logo': logo})
5.配置url
from django.conf.urls import url from . import views urlpatterns = [ url(r'^$', views.index, name='index'), url(r'^list/$', views.goodslist, name='list'), url(r'^pwd/$', views.userpwd, name='pwd'), ]
視圖代碼: def index(request): return render(request, 'temtest/index2.html', { 't1': '<h1>hello</h1>' }) 模板代碼: {{t1}}
會被自動轉義的字符
< 會轉換爲< > 會轉換爲> ' (單引號) 會轉換爲' " (雙引號)會轉換爲 " & 會轉換爲 &
{{t1|escape}}
關閉轉義
{{ data|safe }}
{ % autoescape off %} {{ body }} { % endautoescape %}
字符串字面值
{ { data|default:"<b>123</b>" }}
{ { data|default:"<b>123</b>" }}
def csrf1(request): return render(request,'booktest/csrf1.html') def csrf2(request): uname=request.POST['uname'] return render(request,'booktest/csrf2.html',{'uname':uname})
url(r'^csrf1/$', views.csrf1), url(r'^csrf2/$', views.csrf2),
<html> <head> <title>Title</title> </head> <body> <form method="post" action="/crsf2/"> <input name="uname"><br> <input type="submit" value="提交"/> </form> </body> </html>
<html> <head> <title>Title</title> </head> <body> {{ uname }} </body> </html>
防csrf的使用
<form> {% csrf_token %} ... </form>
取消保護
from django.views.decorators.csrf import csrf_exempt @csrf_exempt def csrf2(request): uname=request.POST['uname'] return render(request,'booktest/csrf2.html',{'uname':uname})
保護原理
<input type='hidden' name='csrfmiddlewaretoken' value='nGjAB3Md9ZSb4NmG1sXDolPmh3bR2g59' />
驗證碼視圖
ImageFont表示字體對象,ubuntu的字體路徑爲「/usr/share/fonts/truetype/freefont」
代碼以下:
from django.http import HttpResponse def verifycode(request): #引入繪圖模塊 from PIL import Image, ImageDraw, ImageFont #引入隨機函數模塊 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 = 'ABCD123EFGHIJK456LMNOPQRS789TUVWXYZ0' #隨機選取4個值做爲驗證碼 rand_str = '' for i in range(0, 4): rand_str += str1[random.randrange(0, len(str1))] #構造字體對象 font = ImageFont.truetype('FreeMono.ttf', 23) #構造字體顏色 fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255)) #繪製4個字 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 #內存文件操做 import cStringIO buf = cStringIO.StringIO() #將圖片保存在內存中,文件類型爲png im.save(buf, 'png') #將內存中的圖片數據返回給客戶端,MIME類型爲圖片png return HttpResponse(buf.getvalue(), 'image/png')
配置url
from . import viewsUtil urlpatterns = [ url(r'^verifycode/$', viewsUtil.verifycode), ]
顯示驗證碼
<img id='verifycode' src="/verifycode/" alt="CheckCode"/>
<script type="text/javascript" src="/static/jquery-1.12.4.min.js"></script> <script type="text/javascript"> $(function(){ $('#verifycodeChange').css('cursor','pointer').click(function() { $('#verifycode').attr('src',$('#verifycode').attr('src')+1) }); }); </script> <img id='verifycode' src="/verifycode/?1" alt="CheckCode"/> <span id='verifycodeChange'>看不清,換一個</span>
<form method='post' action='/verifycodeValid/'> <input type="text" name="vc"> <img id='verifycode' src="/verifycode/?1" alt="CheckCode"/> <span id='verifycodeChange'>看不清,換一個</span> <br> <input type="submit" value="提交"> </form>
驗證
from django.http import HttpResponse def verifycodeValid(request): vc = request.POST['vc'] if vc.upper() == request.session['verifycode']: return HttpResponse('ok') else: return HttpResponse('no')
urlpatterns = [ url(r'^verifycodeValid/$', views.verifycodeValid), ]
第三方
配置靜態文件
STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ]
mysite/static/myapp/
/static/my_app/myexample.jpg
{ % load static from staticfiles %} <img src="{ % static "my_app/myexample.jpg" %}" alt="My image"/>
from django.http import HttpResponse class MyException(): def process_exception(request,response, exception): return HttpResponse(exception.message)
MIDDLEWARE_CLASSES = ( 'test1.myexception.MyException', ... )
pic=models.ImageField(upload_to='cars/')
pip install Pillow==3.4.1
MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")
<html> <head> <title>文件上傳</title> </head> <body> <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> </body> </html>
from django.conf import settings def upload(request): if request.method == "POST": f1 = request.FILES['pic'] 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")
python manage.py createsuperuser 而後按提示填寫用戶名、郵箱、密碼
from django.contrib import admin from models import * admin.site.register(HeroInfo)
class HeroAdmin(admin.ModelAdmin): ...
admin.site.register(HeroInfo,HeroAdmin)
@admin.register(HeroInfo) class HeroAdmin(admin.ModelAdmin):
列表頁選項
「操做選項」的位置
class HeroAdmin(admin.ModelAdmin): actions_on_top = True actions_on_bottom = True
list_display
在models.py文件中 from django.db import models from tinymce.models import HTMLField from django.utils.html import format_html class HeroInfo(models.Model): hname = models.CharField(max_length=10) hcontent = HTMLField() isDelete = models.BooleanField() def hContent(self): return format_html(self.hcontent) 在admin.py文件中 class HeroAdmin(admin.ModelAdmin): list_display = ['hname', 'hContent']
在models.py中HeroInfo類的代碼改成以下: def hContent(self): return format_html(self.hcontent) hContent.admin_order_field = 'hname'
在models.py中爲HeroInfo類增長方法hName: def hName(self): return self.hname hName.short_description = '姓名' hContent.short_description = '內容' 在admin.py頁中註冊 class HeroAdmin(admin.ModelAdmin): list_display = ['hName', 'hContent']
list_filter
class HeroAdmin(admin.ModelAdmin): ... list_filter = ['hname', 'hcontent']
list_per_page
class HeroAdmin(admin.ModelAdmin): ... list_per_page = 10
search_fields
class HeroAdmin(admin.ModelAdmin): ... search_fields = ['hname']
增長與修改頁選項
class HeroAdmin(admin.ModelAdmin): ... fields = [('hname', 'hcontent')]
class HeroAdmin(admin.ModelAdmin): ... fieldsets = ( ('base', {'fields': ('hname')}), ('other', {'fields': ('hcontent')}) )
class HeroInline(admin.TabularInline): model = HeroInfo class BookAdmin(admin.ModelAdmin): inlines = [ HeroInline, ]
'DIRS': [os.path.join(BASE_DIR, 'templates')],
屬性
方法
異常exception
建立對象
屬性
方法
建立視圖pagTest
from django.core.paginator import Paginator def pagTest(request, pIndex): list1 = AreaInfo.objects.filter(aParent__isnull=True) p = Paginator(list1, 10) if pIndex == '': pIndex = '1' pIndex = int(pIndex) list2 = p.page(pIndex) plist = p.page_range return render(request, 'booktest/pagTest.html', {'list': list2, 'plist': plist, 'pIndex': pIndex})
配置url
url(r'^pag(?P<pIndex>[0-9]*)/$', views.pagTest, name='pagTest'),
定義模板pagTest.html
<!DOCTYPE html> <html> <head> <title></title> </head> <body> <ul> {%for area in list%} <li>{{area.id}}--{{area.atitle}}</li> {%endfor%} </ul> {%for pindex in plist%} {%if pIndex == pindex%} {{pindex}} {%else%} <a href="/pag{{pindex}}/">{{pindex}}</a> {%endif%} {%endfor%} </body> </html>
引入js文件
修改settings.py關於靜態文件的設置
STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ]
在models.py中定義模型
class AreaInfo(models.Model): aid = models.IntegerField(primary_key=True) atitle = models.CharField(max_length=20) aPArea = models.ForeignKey('AreaInfo', null=True)
生成遷移
python manage.py makemigrations python manage.py migrate
經過workbench向表中填充示例數據
在views.py中編寫視圖
from django.shortcuts import render from django.http import JsonResponse from models import AreaInfo def index(request): return render(request, 'ct1/index.html') def getArea1(request): list = AreaInfo.objects.filter(aPArea__isnull=True) list2 = [] for a in list: list2.append([a.aid, a.atitle]) return JsonResponse({'data': list2}) def getArea2(request, pid): list = AreaInfo.objects.filter(aPArea_id=pid) list2 = [] for a in list: list2.append({'id': a.aid, 'title': a.atitle}) return JsonResponse({'data': list2})
在urls.py中配置urlconf
from django.conf.urls import url from . import views urlpatterns = [ url(r'^$', views.index), url(r'^area1/$', views.getArea1), url(r'^([0-9]+)/$', views.getArea2), ]
主urls.py中包含此應用的url
from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^', include('ct1.urls', namespace='ct1')), url(r'^admin/', include(admin.site.urls)), ]
定義模板index.html
'DIRS': [os.path.join(BASE_DIR, 'templates')],
<!DOCTYPE html> <html> <head> <title>省市區列表</title> </head> <body> <select id="pro"> <option value="">請選擇省</option> </select> <select id="city"> <option value="">請選擇市</option> </select> <select id="dis"> <option value="">請選擇區縣</option> </select> </body> </html>
在模板中引入jquery文件
<script type="text/javascript" src="static/ct1/js/jquery-1.12.4.min.js"></script>
編寫js代碼
<script type="text/javascript"> $(function(){ $.get('area1/',function(dic) { pro=$('#pro') $.each(dic.data,function(index,item){ pro.append('<option value='+item[0]+'>'+item[1]+'</option>'); }) }); $('#pro').change(function(){ $.post($(this).val()+'/',function(dic){ city=$('#city'); city.empty().append('<option value="">請選擇市</option>'); $.each(dic.data,function(index,item){ city.append('<option value='+item.id+'>'+item.title+'</option>'); }) }); }); $('#city').change(function(){ $.post($(this).val()+'/',function(dic){ dis=$('#dis'); dis.empty().append('<option value="">請選擇區縣</option>'); $.each(dic.data,function(index,item){ dis.append('<option value='+item.id+'>'+item.title+'</option>'); }) }) }); }); </script>
下載安裝
tar zxvf django-tinymce-2.4.0.tar.gz
python setup.py install
應用到項目中
INSTALLED_APPS = ( ... 'tinymce', )
TINYMCE_DEFAULT_CONFIG = { 'theme': 'advanced', 'width': 600, 'height': 400, }
urlpatterns = [ ... url(r'^tinymce/', include('tinymce.urls')), ]
from django.db import models from tinymce.models import HTMLField class HeroInfo(models.Model): ... hcontent = HTMLField()
自定義使用
def editor(request): return render(request, 'other/editor.html')
urlpatterns = [ ... url(r'^editor/$', views.editor, name='editor'), ]
<!DOCTYPE html> <html> <head> <title></title> <script type="text/javascript" src='/static/tiny_mce/tiny_mce.js'></script> <script type="text/javascript"> tinyMCE.init({ 'mode':'textareas', 'theme':'advanced', 'width':400, 'height':100 }); </script> </head> <body> <form method="post" action="/content/"> <input type="text" name="hname"> <br> <textarea name='hcontent'>哈哈,這是啥呀</textarea> <br> <input type="submit" value="提交"> </form> </body> </html>
def content(request): hname = request.POST['hname'] hcontent = request.POST['hcontent'] heroinfo = HeroInfo.objects.get(pk=1) heroinfo.hname = hname heroinfo.hcontent = hcontent heroinfo.save() return render(request, 'other/content.html', {'hero': heroinfo})
urlpatterns = [ ... url(r'^content/$', views.content, name='content'), ]
<!DOCTYPE html> <html> <head> <title></title> </head> <body> 姓名:{{hero.hname}} <hr> {%autoescape off%} {{hero.hcontent}} {%endautoescape%} </body> </html>
設置緩存
CACHES={ 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'TIMEOUT': 60, } }
安裝包:pip install django-redis-cache CACHES = { "default": { "BACKEND": "redis_cache.cache.RedisCache", "LOCATION": "localhost:6379", 'TIMEOUT': 60, }, }
鏈接:redis-cli 切換數據庫:select 1 查看鍵:keys * 查看值:get 鍵
單個view緩存
from django.views.decorators.cache import cache_page @cache_page(60 * 15) def index(request): return HttpResponse('hello1') #return HttpResponse('hello2')
模板片段緩存
{% load cache %} {% cache 500 hello %} hello1 <!--hello2--> {% endcache %}
底層的緩存API
from django.core.cache import cache 設置:cache.set(鍵,值,有效時間) 獲取:cache.get(鍵) 刪除:cache.delete(鍵) 清空:cache.clear()
1.在虛擬環境中依次安裝包
pip install django-haystack pip install whoosh pip install jieba
2.修改settings.py文件
INSTALLED_APPS = ( ... 'haystack', )
HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine', 'PATH': os.path.join(BASE_DIR, 'whoosh_index'), } } #自動生成索引 HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
3.在項目的urls.py中添加url
urlpatterns = [ ... url(r'^search/', include('haystack.urls')), ]
4.在應用目錄下創建search_indexes.py文件
# coding=utf-8 from haystack import indexes from models import GoodsInfo class GoodsInfoIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) def get_model(self): return GoodsInfo def index_queryset(self, using=None): return self.get_model().objects.all()
5.在目錄「templates/search/indexes/應用名稱/」下建立「模型類名稱_text.txt」文件
#goodsinfo_text.txt,這裏列出了要對哪些列的內容進行檢索 {{ object.gName }} {{ object.gSubName }} {{ object.gDes }}
6.在目錄「templates/search/」下創建search.html
<!DOCTYPE html> <html> <head> <title></title> </head> <body> {% if query %} <h3>搜索結果以下:</h3> {% for result in page.object_list %} <a href="/{{ result.object.id }}/">{{ result.object.gName }}</a><br/> {% empty %} <p>啥也沒找到</p> {% endfor %} {% if page.has_previous or page.has_next %} <div> {% if page.has_previous %}<a href="?q={{ query }}&page={{ page.previous_page_number }}">{% endif %}« 上一頁{% if page.has_previous %}</a>{% endif %} | {% if page.has_next %}<a href="?q={{ query }}&page={{ page.next_page_number }}">{% endif %}下一頁 »{% if page.has_next %}</a>{% endif %} </div> {% endif %} {% endif %} </body> </html>
7.創建ChineseAnalyzer.py文件
import jieba from whoosh.analysis import Tokenizer, Token class ChineseTokenizer(Tokenizer): def __call__(self, value, positions=False, chars=False, keeporiginal=False, removestops=True, start_pos=0, start_char=0, mode='', **kwargs): t = Token(positions, chars, removestops=removestops, mode=mode, **kwargs) seglist = jieba.cut(value, cut_all=True) for w in seglist: t.original = t.text = w t.boost = 1.0 if positions: t.pos = start_pos + value.find(w) if chars: t.startchar = start_char + value.find(w) t.endchar = start_char + value.find(w) + len(w) yield t def ChineseAnalyzer(): return ChineseTokenizer()
8.複製whoosh_backend.py文件,更名爲whoosh_cn_backend.py
from .ChineseAnalyzer import ChineseAnalyzer 查找 analyzer=StemmingAnalyzer() 改成 analyzer=ChineseAnalyzer()
9.生成索引
python manage.py rebuild_index
10.在模板中建立搜索欄
<form method='get' action="/search/" target="_blank"> <input type="text" name="q"> <input type="submit" value="查詢"> </form>
名詞
使用
celery==3.1.25 celery-with-redis==3.0 django-celery==3.1.17
INSTALLED_APPS = ( ... 'djcelery', } ... import djcelery djcelery.setup_loader() BROKER_URL = 'redis://127.0.0.1:6379/0' CELERY_IMPORTS = ('應用名稱.task')
import time from celery import task @task def sayhello(): print('hello ...') time.sleep(2) print('world ...')
python manage.py migrate
sudo redis-server /etc/redis/redis.conf
python manage.py celery worker --loglevel=info
function.delay(parameters)
#from task import * def sayhello(request): print('hello ...') import time time.sleep(10) print('world ...') # sayhello.delay() return HttpResponse("hello world")
服務器介紹
服務器環境配置
pip freeze > plist.txt
sudo apt-get install python-virtualenv sudo easy_install virtualenvwrapper mkvirtualenv [虛擬環境名稱]
workon [虛擬環境名稱] pip install -r plist.txt
DEBUG = False ALLOW_HOSTS=['*',]表示能夠訪問服務器的ip
WSGI
uWSGI
pip install uwsgi
[uwsgi] socket=外網ip:端口(使用nginx鏈接時,使用socket) http=外網ip:端口(直接作web服務器,使用http) chdir=項目根目錄 wsgi-file=項目中wsgi.py文件的目錄,相對於項目根目錄 processes=4 threads=2 master=True pidfile=uwsgi.pid daemonize=uswgi.log
nginx
sudo apt-get nginx
解壓縮: tar zxvf nginx-1.6.3.tar.gz 進入nginx-1.6.3目錄依次執行以下命令進行安裝: ./configure make sudo make install
sudo conf/nginx.conf 在server下添加新的location項,指向uwsgi的ip與端口 location / { include uwsgi_params;將全部的參數轉到uwsgi下 uwsgi_pass uwsgi的ip與端口; }
靜態文件
location /static { alias /var/www/test5/static/; }
sudo chmod 777 /var/www/test5
mkdir static
STATIC_ROOT='/var/www/test5/static/' STATIC_URL='/static/'
sudo apt-get install git
git
產生
建立github帳號
ssh-keygen -t rsa -C "youremail@example.com"
建立遠程庫
從遠程庫克隆
git clone git@github.com:帳號名/項目名.git
與遠程庫交互
git pull
git push origin master
建立本地倉庫
mkdir test7 cd test7
git init
文件管理
工做區與暫存區
git add 文件1 文件2 ... git add 目錄
git checkout -- 文件名
git status
暫存區與倉庫區
git commit -m '本次提交的說明信息'
當前版本的歷史版本:git log 簡版顯示:git log --pretty=oneline 歷史命令:git reflog
在Git中,用HEAD表示當前版本,也就是最新的提交3628164...882e1e0(注意個人提交ID和你的確定不同),上一個版本就是HEAD^,上上一個版本就是HEAD^^,固然往上100個版本寫100個^比較容易數不過來,因此寫成HEAD~100
對比工做區和倉庫區中某版本某文件的不一樣
git diff HEAD -- 文件名
git reset HEAD^或版本號
刪除文件
rm 文件名 git rm 文件名 git commit -m '說明信息'