Skip to content

Commit 91522a9

Browse files
committed
django listview advanced
1 parent f9b90a3 commit 91522a9

2 files changed

Lines changed: 90 additions & 2 deletions

File tree

_drafts/2015-01-08-first_from_jeklly.markdown

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
author: shellbye
33
comments: true
4-
date: 2015-01-08 11:27:08+00:00
4+
date: 2015-12-28 11:27:08+00:00
55
layout: post
66
slug: first-blog-from-jekyll
77
title: First blog from jekyll
@@ -32,4 +32,10 @@ def index(request):
3232
return True
3333
else:
3434
return False
35-
{% endhighlight %}
35+
{% endhighlight %}
36+
37+
This is a link about [Wiki]{:target="_blank"}.
38+
This ia a link in my owe [site]{:target="_blank"}.
39+
40+
[Wiki]:https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Common_non-standard_request_fields
41+
[site]:/blog/poet/
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
author: shellbye
3+
comments: true
4+
date: 2015-12-29 10:27:08+00:00
5+
layout: post
6+
slug: Django_ListView_Advanced
7+
title: Advanced Django ListView
8+
categories:
9+
- tech_world
10+
tags:
11+
- Django
12+
---
13+
14+
之前学习Djang时写过一个入门版本的关于ListView的[笔记]{:target="_blank"},
15+
但是其中的东西都笔记基础,没法进行高级的定制,所以有了这篇笔记,
16+
纪录下自己最新的一些心得。
17+
18+
###1.添加返回数据
19+
20+
[上一篇]{:target="_blank"}笔记,假如现在你要在新闻的列表页中集中显示所有的新闻类别,
21+
要怎么做呢?因为你把很多的逻辑都托管给Django了,所以这个时候,新添加的逻辑也是要依赖于Django的,
22+
比如你要新添加的数据,就要用到[`get_context_data`]{:target="_blank"}这个函数了,
23+
官网中关于`get_context_data`的介绍是:
24+
25+
> Returns context data for displaying the list of objects.
26+
27+
这是一个字典,其中默认已经包含了四个对象,一个是返回的对象列表和三个关于分页的对象。
28+
现在我们要在其中添加东西,那就就自己实现一遍这个函数就可以了,代码如下:
29+
30+
{% highlight python %}
31+
def get_context_data(self, **kwargs):
32+
# 先通过调用父类的方法获取到原始的context对象,其中包含上面提到的四个对象
33+
context = super(NewsList, self).get_context_data(**kwargs)
34+
# 在其中添加我们想要添加的对象,这样context就有五个对象了
35+
context['category_list'] = NewsCategory.objects.all()
36+
return context
37+
{% endhighlight %}
38+
39+
然后在`templates`中,我们就可以直接使用`category_list`这个对象了,像这样:
40+
41+
{% highlight python %}
42+
{% raw %}
43+
{% for c in category_list %}
44+
{{c.title}}
45+
{% endfor %}
46+
{% endraw %}
47+
{% endhighlight %}
48+
49+
###2.自定义返回对象集
50+
[上一篇]{:target="_blank"}笔记中,我们是直接获取的所有的新闻,
51+
现在假设我们要添加一个搜索功能,按照新闻标题进行搜索,然后只返回那些命中搜索的新闻,
52+
这就需要过滤返回的结果集了,基于上面的内容,我们最容易想到的就是在`get_context_data`中,
53+
对其中的`object_list`进行过滤,比如在`return`语句前添加如下一行:
54+
55+
{% highlight python %}
56+
context['news_list'] = context['news_list'].filter(title__contains='search_text')
57+
{% endhighlight %}
58+
59+
这样的写法,当有分页功能时(大多数情况下是有的),就会出现如下错误:
60+
61+
> AssertionError at Cannot filter a query once a slice has been taken.
62+
63+
官网的解释在[这里],说白了就是一旦分页了,也就是`slice`了之后,这个查询就在数据库里执行过了,
64+
所以这个时候就没法继续去`filter`了。所以这并不是一个优雅的解决方案,优雅的方案是使用正确的函数,
65+
这里正确的函数就是[`get_queryset`]{:target="_blank"}这个函数了,比如:
66+
67+
{% highlight python %}
68+
def get_queryset(self):
69+
if 'q' in self.request.GET:
70+
return News.objects.filter(title__contains=self.request.GET['q'])
71+
return super(NewsList, self).get_queryset()
72+
{% endhighlight %}
73+
74+
了解一个框架的最佳方式就是要懂其常用函数的功能,那么写一个框架的最佳方式,
75+
就是函数名一定要见名知意,不然找正确的函数就比较痛苦了。
76+
77+
78+
[笔记]:/blog/tech_world/django_ListView_DetailView_basic/
79+
[上一篇]:/blog/tech_world/django_ListView_DetailView_basic/
80+
[`get_context_data`]:https://docs.djangoproject.com/en/1.9/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin.get_context_data
81+
[这里]:https://docs.djangoproject.com/en/1.9/topics/db/queries/#limiting-querysets
82+
[`get_queryset`]:https://docs.djangoproject.com/en/1.9/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin.get_queryset

0 commit comments

Comments
 (0)