当前位置:K88软件开发文章中心网站服务器框架django → 文章内容

Django 高级视图和URL配置

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-25 14:19:18

式匹配成功, page() 函数将使用正则表达式传递过来的num的值。(注:我们已经注意到设置默认参数值是字符串 ‘1’ ,不是整数1 。为了保持一致,因为捕捉给num 的值总是字符串。就像前面解释的一样,这种技术与配置选项的联用是很普遍的。 以下这个例子比提供视图配置选项一节中的例子有些许的改进。def my_view(request, template_name='mysite/my_view.html'): var = do_something() return render_to_response(template_name, {'var': var})特殊情况下的视图有时你有一个模式来处理在你的URLconf中的一系列URL,但是有时候需要特别处理其中的某个URL。 在这种情况下,要使用将URLconf中把特殊情况放在首位的线性处理方式 。比方说,你可以考虑通过下面这个URLpattern所描述的方式来向Django的管理站点添加一个目标页面urlpatterns = patterns('', # ... ('^([^/]+)/([^/]+)/add/$', views.add_stage), # ...)这将匹配像 /myblog/entries/add/ 和 /auth/groups/add/ 这样的URL 。然而,对于用户对象的添加页面(/auth/user/add/ )是个特殊情况,因为它不会显示所有的表单域,它显示两个密码域等等。 我们 可以 在视图中特别指出以解决这种情况:def add_stage(request, app_label, model_name): if app_label == 'auth' and model_name == 'user': # do special-case code else: # do normal code不过,就如我们多次在这章提到的,这样做并不优雅: 因为它把URL逻辑放在了视图中。 更优雅的解决方法是,我们要利用URLconf从顶向下的解析顺序这个特点:urlpatterns = patterns('', # ... ('^auth/user/add/$', views.user_add_stage), ('^([^/]+)/([^/]+)/add/$', views.add_stage), # ...)在这种情况下,象 /auth/user/add/ 的请求将会被 user_add_stage 视图处理。 尽管URL也匹配第二种模式,它会先匹配上面的模式。 (这是短路逻辑。)从URL中捕获文本每个被捕获的参数将被作为纯Python字符串来发送,而不管正则表达式中的格式。 举个例子,在这行URLConf中:(r'^articles/(?P<year>\d{4})/$', views.year_archive),尽管 \d{4} 将只匹配整数的字符串,但是参数 year 是作为字符串传至 views.year_archive() 的,而不是整型。当你在写视图代码时记住这点很重要,许多Python内建的方法对于接受的对象的类型很讲究。 许多内置Python函数是挑剔的(这是理所当然的)只接受特定类型的对象。 一个典型的的错误就是用字符串值而不是整数值来创建 datetime.date 对象:>>> import datetime>>> datetime.date('1993', '7', '9')Traceback (most recent call last): ...TypeError: an integer is required>>> datetime.date(1993, 7, 9)datetime.date(1993, 7, 9)回到URLconf和视图处,错误看起来很可能是这样:# urls.pyfrom django.conf.urls.defaults import *from mysite import viewsurlpatterns = patterns('', (r'^articles/(\d{4})/(\d{2})/(\d{2})/$', views.day_archive),)# views.pyimport datetimedef day_archive(request, year, month, day): # The following statement raises a TypeError! date = datetime.date(year, month, day)因此, day_archive() 应该这样写才是正确的:def day_archive(request, year, month, day): date = datetime.date(int(year), int(month), int(day))注意,当你传递了一个并不完全包含数字的字符串时, int() 会抛出 ValueError 的异常,不过我们已经避免了这个错误,因为在URLconf的正则表达式中已经确保只有包含数字的字符串才会传到这个视图函数中。决定URLconf搜索的东西当一个请求进来时,Django试着将请求的URL作为一个普通Python字符串进行URLconf模式匹配(而不是作为一个Unicode字符串)。 这并不包括 GET 或 POST 参数或域名。 它也不包括第一个斜杠,因为每个URL必定有一个斜杠。例如,在向 http://www.example.com/myapp/ 的请求中,Django将试着去匹配 myapp/ 。在向http://www.example.com/myapp/?page=3 的请求中,Django同样会去匹配 myapp/ 。在解析URLconf时,请求方法(例如, POST , GET , HEAD )并 不会 被考虑。 换而言之,对于相同的URL的所有请求方法将被导向到相同的函数中。 因此根据请求方法来处理分支是视图函数的责任。视图函数的高级概念说到关于请求方法的分支,让我们来看一下可以用什么好的方法来实现它。 考虑这个 URLconf/view 设计:# urls.pyfrom django.conf.urls.defaults import *from mysite import viewsurlpatterns = patterns('', # ... (r'^somepage/$', views.some_page), # ...)# views.pyfrom django.http import Http404, HttpResponseRedirectfrom django.shortcuts import render_to_responsedef some_page(request): if request.method == 'POST': do_something_for_post() return HttpResponseRedirect('/someurl/') elif request.method == 'GET': do_something_for_get() return render_to_response('page.html') else: raise Http404()在这个示例中,some_page() 视图函数对POST 和GET 这两种请求方法的处理完全不同。 它们唯一的共同点是共享一个URL地址: /somepage/.正如大家所看到的,在同一个视图函数中对POST 和GET 进行处理是一种很初级也很粗糙的做法。 一个比较好的设计习惯应该是,用两个分开的视图函数——一个处理POST 请求,另一个处理GET 请求,然后在相应的地方分别进行调用。我们可以像这样做:先写一个视图函数然后由它来具体分派其它的视图,在之前或之后可以执行一些我们自定的程序逻辑。 下边的示例展示了这个技术是如何帮我们改进前边那个简单的some_page() 视图的:# views.pyfrom django.http import Http404, HttpResponseRedirectfrom django.shortcuts import render_to_responsedef method_splitter(request, GET=None, POST=None): if request.method == 'GET' and GET is not None: return GET(request) elif request.method == 'POST' and POST is not None: return POST(request) raise Http404def some_page_get(request): assert request.method == 'GET' do_something_for_get() return re

上一页  [1] [2] [3] [4] [5] [6]  下一页


Django 高级视图和URL配置