Django视图和模板

1.编写视图

```

def detail(request, question_id):

return HttpResponse("You're looking at question %s." % question_id)

def results(request, question_id):

response = "You're looking at the results of question %s."

return HttpResponse(response % question_id)

def vote(request, question_id):

return HttpResponse("You're voting on question %s." % question_id)

```

2.在app的urls.py文件下加入url模式。

3.每个视图至少做两件事之一:返回一个包含请求页面的HttpResponse对象或者弹出一个类似Http404的异常。

4.添加模板

- 快捷方式:render()

- render()函数的第一个位置参数是请求对象(就是view函数的第一个参数),第二个位置参数是模板。还可以有一个可选的第三参数,一个字典,包含需要传递给模板的数据。最后render函数返回一个经过字典数据渲染过的模板封装而成的HttpResponse对象。

5.返回404错误

- 快捷方式:get_object_or_404()

6.使用模板系统

7.删除模板中硬编码的URLs

8.URL names的命名空间

- Django是如何区分这些app之间的URL name呢?

- 答案是使用URLconf的命名空间。在polls/urls.py文件的开头部分,添加一个app_name的变量来指定该应用的命名空间

1.导入方式优化:`from . import views`

2.使用具名分组:在 Python 正则表达式中,具名分组的句法是 (?P<name>pattern) ,其中 name 是分组的名称, pattern 是要匹配的模式。

正则:`url(r'^reviews/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.review_detail)`

具名分组:`url(r'^reviews/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$',views.review_detail)`

- 不同之处:捕获的值以关键字参数传给视图函数,而不是位置参数。

**注意**:虽然 [0-9]{4} 只匹配字符串中的整数,但是传给 views.year_archive() 视图函数的 year 参数是字符串,而不是整数。

例如:对 /reviews/2003/03/03/ 的请求调用

```

views.review_detail(request,year='2003',month='03',day='03')

```

函数。

- 匹配/分组算法

URL 配置解析器解析正则表达式中具名分组和非具名分组所采用的算法如下:

1.如果有具名分组,使用具名分组,忽略非具名分组。

2.否则,以位置参数传递所有非具名分组。

不论如何,额外的关键字参数都会传给视图。

为视图的参数指定默认值:

```

URL 配置

from django.conf.urls import url

from . import views

urlpatterns = [

url(r'^reviews/$', views.page),

url(r'^reviews/page(?P<num>[0-9]+)/$', views.page),

]

```

```

视图(在 reviews/views.py 文件中)

def page(request, num="1"):

```

在上述示例中,两个 URL 模式指向同一个视图,即 views.page ,但是第一个模式没有从 URL 中匹配任何内容。如果匹配第一个模式, page() 函数使用 num 的默认值,即 "1" ;如果匹配第二个模式, page() 函数使用正则表达式匹配的 num 值。

引入其他url配置:

`url(r'^community/',include('django_website.aggregator.urls'))`

注意,这里的正则表达式没有 $ (匹配字符串末尾的符号),但是末尾有斜线。Django 遇到 include() 时,会把截至那一位置匹配的 URL 截断,把余下的字符串传给引入它的 URL 配置,做进一步处理。

### 给视图函数传递参数

```

urlpatterns = [

url(r'^reviews/(?P<year>[0-9]{4})/$',

views.year_archive,

{'foo': 'bar'}),]

```

- 对这个示例来说,请求 /reviews/2005/ 时,Django 调用views.year_archive(request, year='2005',foo='bar') 。聚合(syndication)框架通过这种方式把元数据和选项传给视图。

- 处理冲突:

有可能 URL 模式捕获了具名关键字参数,又在第三个参数中传递同名的参数。此时,Django使用字典中的参数,而不是从 URL 中捕获的参数。

### 给 include() 传递额外参数

- 被引入的 URL 配置中的每一行都将收到额外的参数。

第一种:`urlpatterns = [url(r'^reviews/', include('inner'),{'reviewid': 3}),]`

第二种:

```

urlpatterns = [url(r'^reviews/', include('inner')),]

url(r'^archive/$', views.archive, {'reviewid': 3})

```

- 注意,不管 URL 模式是否能接收参数,额外的参数都将传给被引入的 URL 配置的每个模式。鉴于此,仅当确定被引入的 URL 配置中的每个视图都接收传入的额外参数时,才应该这么做。

### url反向解析

Django 在不同的层中提供了执行 URL 反转所需的工具:

- 在模板中,使用 url 模板标签。

```

from django.conf.urls import url

from . import views

urlpatterns = [

url(r'^reviews/([0-9]{4})/$', views.year_archive,

name='reviews-year-archive'),

]

```

根据这个设计,nnnn 年的存档对应的 URL 是 /reviews/nnnn/ 。在模板中可以使用下述代码获取这个 URL:

```

<a href="{% url 'reviews-year-archive' 2012 %}">2012Archive</a>

```

{# 或者把年份存储在一个模板上下文变量中:#}

```

<ul>

{% for yearvar in year_list %}

<li><a href="{% url 'reviews-year-archive' yearvar %}">{{

yearvar }} Archive</a></li>

{% endfor %}

</ul>

```

- 在 Python 代码中,使用 django.core.urlresolvers.reverse() 函数。

```

from django.core.urlresolvers import reverse

from django.http import HttpResponseRedirect

def redirect_to_year(request):

year = 2012

return HttpResponseRedirect(reverse('reviews-year-archive',args=(year,)))

```

- 在处理 Django 模型实例 URL 相关的高层代码中,使用get_absolute_url() 方法。

### url命名

- 为了执行 URL 反转,要像前述示例那样为 URL 模式命名。URL 模式的名称可以包含任何字符串,而不限定于必须是有效的 Python 标识符。为 URL 模式命名时,要确保不与其他应用中的名称冲突。

### URL 命名空间和引入的 URL 配置(待补充)

```

url(r'^reviews/', include('reviews.urls',

namespace='author-reviews',

app_name='reviews')),

```

posted @ 2019-04-21 13:27  乄一叶知秋  阅读(198)  评论(0编辑  收藏  举报