在基于类的Django listview
中,当一个值分配给paginate_by
时,它会确保object_list
方法中的get_context_data
仅限于只有那个特定页面需要的对象。
E.g。 get_queryset
可能会返回1000个对象,但如果单个页面要显示20个对象,则object_list
中只有{20}个对象可用get_context_data
。在处理大型查询集时,这是一个很好的优化。
如何在基于函数的视图中创建相同的行为?在典型的实现中(并且采用上述示例),将评估所有1000个对象,然后在分页中使用。这意味着在这种特殊情况下,CBV明显优于基于功能的视图。基于功能的视图可以提供相同的功能吗?一个说明性的例子会很棒(或者说他们不能解决这类问题)。
这是实际的CBV:
class PostListView(ListView):
model = Post
paginate_by = 20
template_name = "post_list.html"
def get_queryset(self):
return all_posts()
def get_context_data(self, **kwargs):
context = super(PostListView, self).get_context_data(**kwargs)
posts = retrieve_posts(context["object_list"]) #retrieves 20 posts
return context
这是实际的FBV:
def post_list(request, *args, **kwargs):
form = PostListForm()
context = {}
obj_list = all_posts()
posts = retrieve_posts(obj_list) #retrieves 1000 posts
paginator = Paginator(posts, 20)
page = request.GET.get('page', '1')
try:
page = paginator.page(page)
except PageNotAnInteger:
page = paginator.page(1)
except EmptyPage:
page = paginator.page(paginator.num_pages)
retrieve_posts()
函数:
def retrieve_posts(post_id_list):
my_server = redis.Redis(connection_pool=POOL)
posts = []
pipeline1 = my_server.pipeline()
for post_id in post_id_list:
hash_name="pt:"+str(post_id)
pipeline1.hgetall(hash_name)
result1 = pipeline1.execute()
count = 0
for hash_obj in result1:
posts.append(hash_obj)
count += 1
return posts
all_posts()
函数:
def all_posts():
my_server = redis.Redis(connection_pool=POOL)
return my_server.lrange("posts:1000", 0, -1) #list of ids of 1000 posts
两种方法的响应时间差异(通过newrelic):
蓝色部分正在处理视图。
答案 0 :(得分:2)
请勿使用原始对象列表调用retreive_posts
。在分页后使用页面对象列表。
posts = retrieve_posts(page.obj_list)