我们用Django开发,比如做一个博客,我们需要做一个文章列表,文章详情页,这种需求是比较普遍的,所以Django中提供了Class-Based Views。
有时候我们想直接渲染一个模板,不得不写一个视图函数
1
2
|
def render_template_view(request): return render(request, '/path/to/template.html' ) |
其实可以用 TemplateView 可以直接写在 urls.py 中,不需要定义一个这样的函数。
这样的例子还有很多,下面一一介绍:
在urls.py中使用类视图的时候都是调用它的 .as_view() 函数
一,Base Views
1. django.views.generic.base.View
这个类是通用类的基类,其它类都是继承自这个类,一般不会用到这个类,个人感觉用函数更简单些。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# views.py from django.http import HttpResponse from django.views.generic import View class MyView(View): def get( self , request, * args, * * kwargs): return HttpResponse( 'Hello, World!' ) # urls.py from django.conf.urls import patterns, url from myapp.views import MyView urlpatterns = patterns('', url(r '^mine/$' , MyView.as_view(), name = 'my-view' ), ) |
2. django.views.generic.base.TemplateView
在 get_context_data() 函数中,可以传一些 额外内容 到 模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
# views.py from django.views.generic.base import TemplateView from articles.models import Article class HomePageView(TemplateView): template_name = "home.html" def get_context_data( self , * * kwargs): context = super (HomePageView, self ).get_context_data( * * kwargs) context[ 'latest_articles' ] = Article.objects. all ()[: 5 ] return context # urls.py from django.conf.urls import patterns, url from myapp.views import HomePageView urlpatterns = patterns('', url(r '^$' , HomePageView.as_view(), name = 'home' ), ) |
3. django.views.generic.base.RedirectView
用来进行跳转, 默认是永久重定向(301),可以直接在urls.py中使用,非常方便:
1
2
3
4
5
6
7
|
from django.conf.urls import patterns, url from django.views.generic.base import RedirectView urlpatterns = patterns('', url(r '^go-to-django/$' , RedirectView.as_view(url = 'http://djangoproject.com' ), name = 'go-to-django' ), url(r '^go-to-ziqiangxuetang/$' , RedirectView.as_view(url = 'http://www.ziqiangxuetang.com' ,permant = False ), name = 'go-to-zqxt' ), ) |
其它的使用方式:(new in Django1.6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# views.py from django.shortcuts import get_object_or_404 from django.views.generic.base import RedirectView from articles.models import Article class ArticleCounterRedirectView(RedirectView): url = ' # 要跳转的网址, # url 可以不给,用 pattern_name 和 get_redirect_url() 函数 来解析到要跳转的网址 permanent = False #是否为永久重定向, 默认为 True query_string = True # 是否传递GET的参数到跳转网址,True时会传递,默认为 False pattern_name = 'article-detail' # 用来跳转的 URL, 看下面的 get_redirect_url() 函数 # 如果url没有设定,此函数就会尝试用pattern_name和从网址中捕捉的参数来获取对应网址 # 即 reverse(pattern_name, args) 得到相应的网址, # 在这个例子中是一个文章的点击数链接,点击后文章浏览次数加1,再跳转到真正的文章页面 def get_redirect_url( self , * args, * * kwargs): If url is not set , get_redirect_url() tries to reverse the pattern_name using what was captured in the URL (both named and unnamed groups are used). article = get_object_or_404(Article, pk = kwargs[ 'pk' ]) article.update_counter() # 更新文章点击数,在models.py中实现 return super (ArticleCounterRedirectView, self ).get_redirect_url( * args, * * kwargs) # urls.py from django.conf.urls import patterns, url from django.views.generic.base import RedirectView from article.views import ArticleCounterRedirectView, ArticleDetail urlpatterns = patterns('', url(r '^counter/(?P<pk>\d+)/$' , ArticleCounterRedirectView.as_view(), name = 'article-counter' ), url(r '^details/(?P<pk>\d+)/$' , ArticleDetail.as_view(), name = 'article-detail' ), ) |
二,Generic Display View (通用显示视图)
1. django.views.generic.detail.DetailView
DetailView 有以下方法:
-
get()
-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
# views.py from django.views.generic.detail import DetailView from django.utils import timezone from articles.models import Article class ArticleDetailView(DetailView): model = Article # 要显示详情内容的类 template_name = 'article_detail.html' # 模板名称,默认为 应用名/类名_detail.html(即 app/modelname_detail.html) # 在 get_context_data() 函数中可以用于传递一些额外的内容到网页 def get_context_data( self , * * kwargs): context = super (ArticleDetailView, self ).get_context_data( * * kwargs) context[ 'now' ] = timezone.now() return context # urls.py from django.conf.urls import url from article.views import ArticleDetailView urlpatterns = [ url(r '^(?P<slug>[-_\w]+)/$' , ArticleDetailView.as_view(), name = 'article-detail' ), ] |
article_detail.html
1
2
3
4
5
6
7
|
< h1 >标题:{{ object.title }}</ h1 > < p >内容:{{ object.content }}</ p > < p >发表人: {{ object.reporter }}</ p > < p >发表于: {{ object.pub_date|date }}</ p > < p >日期: {{ now|date }}</ p > |
2. django.views.generic.list.ListView
ListView 有以下方法:
-
get()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# views.py from django.views.generic. list import ListView from django.utils import timezone from articles.models import Article class ArticleListView(ListView): model = Article def get_context_data( self , * * kwargs): context = super (ArticleListView, self ).get_context_data( * * kwargs) context[ 'now' ] = timezone.now() return context # urls.py: from django.conf.urls import url from article.views import ArticleListView urlpatterns = [ url(r '^$' , ArticleListView.as_view(), name = 'article-list' ), ] |
article_list.html
1
2
3
4
5
6
7
8
|
< h1 >文章列表</ h1 > < ul > {% for article in object_list %} < li >{{ article.pub_date|date }} - {{ article.headline }}</ li > {% empty %} < li >抱歉,目前还没有文章。</ li > {% endfor %} </ ul > |