您的位置:首页 > 编程语言 > Go语言

django关于URL、Template、Model的一些高级应用

2012-07-20 00:00 246 查看
URL配置的一些技巧:

1、添加视图前缀的方法:

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'),
)

2、使用命名参数:

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),
)

视图进行如下匹配:

month_archive(request, year='2006', month='03')

使用命名参数顺序如下:

如果包含命名参数,则忽略所有未命名参数

如果没有,则使用顺序参数调用

以上两种方式中,都可以传递额外选项。

3、生成通用视图

# 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})

现重构如下:

# 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})


4、匹配特例
在通过正则表达式处理大量url请求时,可能需要对某个特定的url请求调用不同的视图处理函数。解决的方法是将需要匹配的url特例放在通用的正则表达式前,如下例:

urlpatterns = patterns('',
# ...
('^auth/user/add/$', views.user_add_stage),
('^([^/]+)/([^/]+)/add/$', views.add_stage),
# ...
)

5、包含其他URL

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不要以$结尾!!!

6、传递额外参数

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列表:

Text node: "Hello, "

Variable node: person.name

Text node: ".\n\n"

IfEqual node: name.birthday and today

在编译完成后,会依次调用每个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的子类。

创建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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  django