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