在一类基于Django的listview
,当一个下发的一个值paginate_by
,它确保object_list
提供get_context_data
方法局限于只有那些需要的对象该特定页面。优化在基于功能的视图(在Django)分页
E.g. get_queryset
可能会返回1000个对象,但是如果单个页面显示20个对象,则只有20个对象可用,其中object_list
位于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的)的响应时间:
蓝色部分是视图的处理。
哈桑你好,你似乎有这个看法是正确的。什么似乎是问题? – e4c5
嘿@ e4c5。我检索的对象是redis哈希。在基于类的视图中,上下文被限制为20个对象(感谢'paginate_by'),而在FBV中,我最终执行整个1000个对象列表的检索。因此,与CBV相比,服务器响应时间是我的FBV的两倍。 –
你可以把两个methodos的绝对时间,并张贴retrieve_object_list方法 – e4c5