View的其他子类
ListView
继承自MultipleObjectTemplateResponseMixin
- 该类继承自TemplateResponseMixin
获取模板名字
- 首先根据template_name获取
如果没找到
- 自己根据应用的名字,关联模型的名字,_list.html去查找
- 例如:App/book_list.html去查找
继承自BaseListView
继承自MultipleObjectMixin
继承自ContextMixin
- 该类做了模型查询,以及分页等等功能
- get_queryset查询结果集
- model/query_Set
- 继承自View
- 默认实现了get,渲染成了response
View的子类中有ListView:
class ListView(MultipleObjectTemplateResponseMixin, BaseListView):
"""
Render some list of objects, set by `self.model` or `self.queryset`.
`self.queryset` can actually be any iterable of items, not just a queryset.
"""
这个类比较奇怪,只写了注释没有其他的代码,现在进行LIstView的实验。
使用ListView来渲染列表
所需内容
集合数据
在Models.py中创建模型:
from django.db import models
class Book(models.Model):
ba_name =models.CharField(max_length=32)
迁移数据库
views.py中新建HelloListView类继承自ListView:
class HelloListView(ListView):
template_name='BookList.html'
model = Book
urls.py添加:
url(r'^listview/',views.HelloListView.as_view(),name='listview'),
模板
新建BookList.html页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BookList</title>
</head>
<body>
{% for book in object_list %}
<li>{{ book.ba_name }}</li>
{% endfor %}
</body>
</html>
访问测试
所以现在加载列表不需要再去写查询语句,只需要调用Listview所带的方法。
DetailView
继承自SingleObjectTemplateResponseMixin单个对象模板响应的复合类
- 继承自TemplateResponseMixin
- 重写了获取模板名字的方法
继承自BaseDetailView
- 继承自View
- 继承自SingleObjectMixin
class DetailView(SingleObjectTemplateResponseMixin, BaseDetailView): """ Render a "detail" view of an object. By default this is a model instance looked up from `self.queryset`, but the view will support display of *any* object by overriding `self.get_object()`. """
实验:使用DetailView来查询具体的一本书
urls:
url(r'single/(?P<pk>\d+)/',views.HelloDetailView.as_view(),name='single')
views:
<meta charset="UTF-8"> <title>book</title> </head> <body> <h2>{{ book.ba_name }}</h2> </body> </html>
访问测试
这样我们就可以通过Detailview来实现访问某一具体的对象的页面。
实验:书籍列表与每本书详情页面联动
BookList.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BookList</title>
</head>
<body>
{% for book in object_list %}
<li><a href="{% url 'cbv:single' pk=book.id %}">{{ book.ba_name }}</a></li>
{% endfor %}
</body>
</html>
测试:
换一种思路改写
利用DetailView继承的SingleObjectTemplateResponseMixin子类(39到43行中):
class SingleObjectTemplateResponseMixin(TemplateResponseMixin):
template_name_field = None
template_name_suffix = '_detail'
def get_template_names(self):
"""
Return a list of template names to be used for the request. May not be
called if render_to_response is overridden. Returns the following list:
* the value of ``template_name`` on the view (if provided)
* the contents of the ``template_name_field`` field on the
object instance that the view is operating upon (if available)
* ``<app_label>/<model_name><template_name_suffix>.html``
"""
try:
names = super(SingleObjectTemplateResponseMixin, self).get_template_names()
except ImproperlyConfigured:
# If template_name isn't specified, it's not a problem --
# we just start with an empty list.
names = []
# If self.template_name_field is set, grab the value of the field
# of that name from the object; this is the most specific template
# name, if given.
if self.object and self.template_name_field:
name = getattr(self.object, self.template_name_field, None)
if name:
names.insert(0, name)
# The least-specific option is the default <app>/<model>_detail.html;
# only use this if the object in question is a model.
if isinstance(self.object, models.Model):
object_meta = self.object._meta
names.append("%s/%s%s.html" % (
object_meta.app_label,
object_meta.model_name,
self.template_name_suffix
))
elif hasattr(self, 'model') and self.model is not None and issubclass(self.model, models.Model):
names.append("%s/%s%s.html" % (
self.model._meta.app_label,
self.model._meta.model_name,
self.template_name_suffix
))
由39到43行中,我们可以看到可以在Template文件夹中新建App文件夹,创建"model_name"+"_detail.html"
文件,然后就可以自动实现每本书的详情页面。
步骤
views:
class HelloDetailView(DetailView):
model = Book
新建html:
测试:
我们还可以用queryset来代替model查询:
views.py:
class HelloDetailView(DetailView):
# template_name = 'Book.html'
# model = Book
queryset = Book.objects.all()
此处评论已关闭