URL配置的一些技巧:html
一、添加視圖前綴的方法:node
from django.conf.urls.defaults import * urlpatterns = patterns('mysite.views', (r'^hello/$', 'hello'), (r'^time/$', 'current_datetime'), (r'^time/plus/(d{1,2})/$', 'hours_ahead'), )
二、使用命名參數:python
from django.conf.urls.defaults import * from mysite import views urlpatterns = patterns('', (r'^articles/(?P<year>\d{4})/$', views.year_archive), (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', views.month_archive), )
視圖進行以下匹配:web
month_archive(request, year='2006', month='03')正則表達式
使用命名參數順序以下:django
三、生成通用視圖app
# urls.py from django.conf.urls.defaults import * from mysite import views urlpatterns = patterns('', (r'^events/$', views.event_list), (r'^blog/entries/$', views.entry_list), ) # views.py from django.shortcuts import render_to_response from mysite.models import Event, BlogEntry def event_list(request): obj_list = Event.objects.all() return render_to_response('mysite/event_list.html', {'event_list': obj_list}) def entry_list(request): obj_list = BlogEntry.objects.all() return render_to_response('mysite/blogentry_list.html', {'entry_list': obj_list})
現重構以下:ide
# urls.py from django.conf.urls.defaults import * from mysite import models, views urlpatterns = patterns('', (r'^events/$', views.object_list, {'model': models.Event}), (r'^blog/entries/$', views.object_list, {'model': models.BlogEntry}), ) # views.py from django.shortcuts import render_to_response def object_list(request, model): obj_list = model.objects.all() template_name = 'mysite/%s_list.html' % model.__name__.lower() return render_to_response(template_name, {'object_list': obj_list})
四、匹配特例
在經過正則表達式處理大量url請求時,可能須要對某個特定的url請求調用不一樣的視圖處理函數。解決的方法是將須要匹配的url特例放在通用的正則表達式前,以下例:函數
urlpatterns = patterns('', # ... ('^auth/user/add/$', views.user_add_stage), ('^([^/]+)/([^/]+)/add/$', views.add_stage), # ... )
五、包含其餘URLui
from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^weblog/', include('mysite.blog.urls')), (r'^photos/', include('mysite.photos.urls')), (r'^about/$', 'mysite.views.about'), )
注意:包含的URL不要以$結尾!!!
六、傳遞額外參數
from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^blog/', include('inner'), {'blogid': 3}), ) # inner.py from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^archive/$', 'mysite.views.archive'), (r'^about/$', 'mysite.views.about'), (r'^rss/$', 'mysite.views.rss'), )
模板的高級技巧:
RequestContext類和Context處理器
下面經過一個例子來看一下RequestContext的使用。
from django.template import loader, Context def view_1(request): # ... t = loader.get_template('template1.html') c = Context({ 'app': 'My app', 'user': request.user, 'ip_address': request.META['REMOTE_ADDR'], 'message': 'I am view 1.' }) return t.render(c) def view_2(request): # ... t = loader.get_template('template2.html') c = Context({ 'app': 'My app', 'user': request.user, 'ip_address': request.META['REMOTE_ADDR'], 'message': 'I am the second view.' }) return t.render(c)
經過使用RequestContext,就能夠簡化上面的代碼:
from django.template import loader, RequestContext def custom_proc(request): "A context processor that provides 'app', 'user' and 'ip_address'." return { 'app': 'My app', 'user': request.user, 'ip_address': request.META['REMOTE_ADDR'] } def view_1(request): # ... t = loader.get_template('template1.html') c = RequestContext(request, {'message': 'I am view 1.'}, processors=[custom_proc]) return t.render(c) def view_2(request): # ... t = loader.get_template('template2.html') c = RequestContext(request, {'message': 'I am the second view.'}, processors=[custom_proc]) return t.render(c)
對於render_to_response()函數,咱們可使用context_instance參數:
from django.shortcuts import render_to_response from django.template import RequestContext def custom_proc(request): "A context processor that provides 'app', 'user' and 'ip_address'." return { 'app': 'My app', 'user': request.user, 'ip_address': request.META['REMOTE_ADDR'] } def view_1(request): # ... return render_to_response('template1.html', {'message': 'I am view 1.'}, context_instance=RequestContext(request, processors=[custom_proc])) def view_2(request): # ... return render_to_response('template2.html', {'message': 'I am the second view.'}, context_instance=RequestContext(request, processors=[custom_proc]))
過濾器函數能夠有一個或兩個參數,第一個參數爲輸入,第二個參數爲選項。下面來看一些例子:
def cut(value, arg): "Removes all values of arg from the given string" return value.replace(arg, '')
{{ somevariable|cut:" " }}
def lower(value): # Only one argument. "Converts a string into all lowercase" return value.lower()
註冊定製過濾器的代碼以下:
from django import template register = template.Library() register.filter('cut', cut) register.filter('lower', lower)
在django中,模板系統的工做分爲兩部分:編譯和渲染。
在編譯的過程當中,django會分析模板標籤,並將其生成相應的django.template.Node對象,該對象中包含有render()函數。可參考下面的例子:
Hello, {{ person.name }}. {% ifequal name.birthday today %} Happy birthday! {% else %} Be sure to come back on your birthday for a splendid surprise message. {% endifequal %}
上面的模板在分析後,會生成以下Node列表:
在編譯完成後,會依次調用每一個Node的render()函數進行渲染。
下面經過一個{% current_time %}標記來演示定製標籤的方法。咱們要實現的標籤的使用方法以下:
<p>The time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p>
首先是編譯函數:
from django import template register = template.Library() def do_current_time(parser, token): try: # split_contents() knows not to split quoted strings. tag_name, format_string = token.split_contents() except ValueError: msg = '%r tag requires a single argument' % token.split_contents()[0] raise template.TemplateSyntaxError(msg) return CurrentTimeNode(format_string[1:-1])
須要注意的是,在編譯函數中不能拋出異常。返回的必定是一個Node的子類。
下面來建立CurrentTimeNode類:
import datetime class CurrentTimeNode(template.Node): def __init__(self, format_string): self.format_string = str(format_string) def render(self, context): now = datetime.datetime.now() return now.strftime(self.format_string)
註冊標籤的方法以下:
register.tag('current_time', do_current_time)
模型的高級應用
添加額外的管理器
# models.py from django.db import models # ... Author and Publisher models here ... class BookManager(models.Manager): def title_count(self, keyword): return self.filter(title__icontains=keyword).count() class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField() num_pages = models.IntegerField(blank=True, null=True) objects = BookManager() def __unicode__(self): return self.title
使用以下:
>>> Book.objects.title_count('django') 4 >>> Book.objects.title_count('python') 18