Job Search Engine
911 浏览 5 years, 8 months
2.2 列表视图
版权声明: 转载请注明出处 http://www.codingsoho.com/CBV显示
接下来我们会通过django将列表在前端显示出来,首先会用django自带的render方法显示
先给一个最简单的实现
ListView
在views里添加列表视图,它从ListView继承而来
from django.views.generic.list import ListView
from .models import JobEntry
# Create your views here.
class JobEntryListView(ListView):
model = JobEntry
路由
jse.urls里添加访问列表的路由
from job_entry.views import JobEntryListView
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^jobentry/$', JobEntryListView.as_view(), name='job_entry_list'),
]
如果现在访问http://127.0.0.1:8000/jobentry/,它会有下面报错
TemplateDoesNotExist at /jobentry/
job_entry/jobentry_list.html
Request Method: GET
Request URL: [http://127.0.0.1](http://127.0.0.1):8000/jobentry/
Django Version: 1.11
Exception Type: TemplateDoesNotExist
Exception Value:
job_entry/jobentry_list.html
Template-loader postmortem
Django tried loading these templates, in this order:
Using engine django:
django.template.loaders.app_directories.Loader: E:\Computer\virtualenv\ijob\env27\lib\site-packages\django\contrib\admin\templates\job_entry\jobentry_list.html (Source does not exist)
django.template.loaders.app_directories.Loader: E:\Computer\virtualenv\ijob\env27\lib\site-packages\django\contrib\auth\templates\job_entry\jobentry_list.html (Source does not exist)
因为我们现在缺少模板文件,它的默认路径在 [yourapp][yourapp_list.html],这个一个相对路径,绝对根目录需要在settings.py里指定。 上面的报错中,可以看到当前的templates搜索路径只在admin和auth模块
模板
修改settings文件
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'),], # (1)
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
# (1)
增加的DIRS
会新增搜索模板文件路径,这样最终添加的模板文件对应路径为[BASE_DIR]\templates\job_entry.jobentry_list.html
接下来实现jobentry_list.html文件
传递给template的变量为object_list,可以通过{{object_list}}语句直接显示
这会是一大串列表,我们用for语句寻呼访问
<H1>{{object_list}}</H1>
<table>
<tr>
<th>title</th>
<th>salary</th>
<th>region</th>
<th>degree</th>
<th>experience</th>
<th>company</th>
<th>industry</th>
<th>description</th>
<th>href</th>
<th>created</th>
</tr>
{% for obj in object_list %}
<tr>
<td>{{obj.title}}</td>
<td>{{obj.salary}}</td>
<td>{{obj.region}}</td>
<td>{{obj.degree}}</td>
<td>{{obj.experience}}</td>
<td>{{obj.company}}</td>
<td>{{obj.industry}}</td>
<td>{{obj.description}}</td>
<td>{{obj.href}}</td>
<td>{{obj.created}}</td>
</tr>
{% endfor %}
</table>
ListView参数配置和函数覆盖
get_context_data
上面例子中,可以看到模板文件里能够操作变量object_list
这个变量,它是从哪儿传递过来的?可以修改吗?
它在MultipleObjectMixin::get_context_data
中赋值
class MultipleObjectMixin(ContextMixin):
def get_context_data(self, **kwargs):
"""
Get the context for this view.
"""
queryset = kwargs.pop('object_list', self.object_list)
page_size = self.get_paginate_by(queryset)
context_object_name = self.get_context_object_name(queryset)
if page_size:
paginator, page, queryset, is_paginated = self.paginate_queryset(queryset, page_size)
context = {
'paginator': paginator,
'page_obj': page,
'is_paginated': is_paginated,
'object_list': queryset
}
else:
context = {
'paginator': None,
'page_obj': None,
'is_paginated': False,
'object_list': queryset
}
if context_object_name is not None:
context[context_object_name] = queryset
context.update(kwargs)
return super(MultipleObjectMixin, self).get_context_data(**context)
我们可以通过重载get_context_data
这个函数来修改这个变量或者传递更多的变量
它也涉及了分页功能,这个我们在后面在详述
context_object_name
添加context_object_name
class JobEntryListView(ListView):
model = JobEntry
context_object_name = 'jobentry_object_list'
这样在模板里也可以使用这个变量,它的值和object_list
是一样的
{% for obj in jobentry_object_list %}
<tr>
<td>{{obj.title}}</td>
<td>{{obj.salary}}</td>
<td>{{obj.region}}</td>
<td>{{obj.degree}}</td>
<td>{{obj.experience}}</td>
<td>{{obj.company}}</td>
<td>{{obj.industry}}</td>
<td>{{obj.description}}</td>
<td>{{obj.href}}</td>
<td>{{obj.created}}</td>
</tr>
{% endfor %}
ordering
可以通过修改ordering
参数改变结果排序,例如我们想改成是创建时间倒叙,可以改成-created
,那么结果会跟默认的相反,列表顺序颠倒了。
template_name
前面的模板我们是在指定文件存放的,也可以根据项目的需求放到自定义位置,该功能可以通过修改template_name
实现
如果我随便改一个位置template_name = 'a.html'
,但是系统指定的位置仍正常放置了html文件,它不会报错,正常工作。但是如果指定位置并没有存放,那么就会继续报错找不到指定文件。从报错可以看到,它总是会找系统指定位置文件的
a.html, job_entry/jobentry_list.html
Request Method: GET
Request URL: [http://127.0.0.1](http://127.0.0.1):8000/jobentry/
Django Version: 1.11
Exception Type: TemplateDoesNotExist
Exception Value:
a.html, job_entry/jobentry_list.html
Template-loader postmortem
Django tried loading these templates, in this order:
Using engine django:
django.template.loaders.filesystem.Loader: E:\Computer\virtualenv\ijob\jse\templates\a.html (Source does not exist)
django.template.loaders.app_directories.Loader: E:\Computer\virtualenv\ijob\env27\lib\site-packages\django\contrib\admin\templates\a.html (Source does not exist)
django.template.loaders.app_directories.Loader: E:\Computer\virtualenv\ijob\env27\lib\site-packages\django\contrib\auth\templates\a.html (Source does not exist)
Using engine django:
django.template.loaders.filesystem.Loader: E:\Computer\virtualenv\ijob\jse\templates\job_entry\jobentry_list.html (Source does not exist)
django.template.loaders.app_directories.Loader: E:\Computer\virtualenv\ijob\env27\lib\site-packages\django\contrib\admin\templates\job_entry\jobentry_list.html (Source does not exist)
django.template.loaders.app_directories.Loader: E:\Computer\virtualenv\ijob\env27\lib\site-packages\django\contrib\auth\templates\job_entry\jobentry_list.html (Source does not exist)
其他
MultipleObjectMixin
涉及的其它功能和配置从下面的代码段可以看出来
class MultipleObjectMixin(ContextMixin):
"""
A mixin for views manipulating multiple objects.
"""
allow_empty = True
queryset = None
model = None
paginate_by = None
paginate_orphans = 0
context_object_name = None
paginator_class = Paginator
page_kwarg = 'page'
ordering = None
很多配置是跟分页相关的,这个后面来学习