Django网络应用开发的5项基础核心技术包括模型(Model)的设计,URL 的设计与配置,View(视图)的编写,Template(模板)的设计和Form(表单)的使用。
会发现,在上一篇中,用到的装饰器和权限操作,不知道从何下手。对于 model 的增删改查,是需要特定的权限才能执行。在后台,对资讯数据进行分页和查询。有些查询需求,比如是某段时间内的资讯还是某个分类下的资讯。在处理这样的情况,需要在创建资讯 model 的时候,清晰知道哪些字段可以作为查询的标识。
newses = News.objects.select_related('category', 'author')
① permission_required
权限操作 Django实战-信息资讯-CMS后台管理-中 在这节中有讲到,如何自定义类视图装饰器,以及 method_decorator 的用法。
@method_decorator([permission_required(News)], name='dispatch')
if start and end:
start_date = datetime.strptime(start, '%Y/%m/%d')
end_date = datetime.strptime(end, '%Y/%m/%d')
newses = newses.filter(pub_time__range=(start_date, end_date))
在过滤处理中,需要清楚怎样获取到前端传来的时间段(起始时间和终止时间)
start = request.GET.get('start')
end = request.GET.get('end')
可以通过 request.GET.get() 来获取管理员查询的某段时间。
if category_id != 0:
newses = newses.filter(category=category_id)
导入Paginator
from django.core.paginator import Paginator
创建分页对象, 然后通过这个对象来调用分页的所有的属性。
# 设置每一页显示几条 创建一个panginator对象
paginator = Paginator(newses, 2)
封装分页函数
def get_pagination_data(self, paginator, page_obj, around_count=2):
current_page = page_obj.number
num_pages = paginator.num_pages
left_has_more = False
right_has_more = +False
if current_page <= around_count + 2:
left_pages = range(1, current_page)
else:
left_has_more = True
left_pages = range(current_page - around_count, current_page)
if current_page >= num_pages - around_count - 1:
right_pages = range(current_page + 1, num_pages + 1)
else:
right_has_more = True
right_pages = range(current_page + 1, current_page + around_count + 1)
return {
'left_pages': left_pages,
'right_pages': right_pages,
'current_page': current_page,
'left_has_more': left_has_more,
'right_has_more': right_has_more,
'num_pages': num_pages
}
对于分页后的数据,需要用 urllib.parse URL解析组件,生成特定的 URL
"url_query": "&"+parse.urlencode({
"start": start,
"end": end,
"title": title,
"category": category_id
})
# 忽略大小写的包含, 过滤的标题中函数定义关键字的新闻
newses = newses.filter(title__icontains=title)
② 资讯列表查询
@method_decorator([xfz_permission_required(News)], name='dispatch')
class NewsList(View):
def get(self, request):
page = int(request.GET.get('p', 1))
start = request.GET.get('start')
end = request.GET.get('end')
title = request.GET.get('title')
category_id = int(request.GET.get('category', 0))
newses = News.objects.select_related('category', 'author')
# 过滤的指定时间之内的新闻
if start and end:
start_date = datetime.strptime(start, '%Y/%m/%d')
end_date = datetime.strptime(end, '%Y/%m/%d')
newses = newses.filter(pub_time__range=(start_date, end_date))
if title:
# 忽略大小写的包含, 过滤的标题中函数定义关键字的新闻
newses = newses.filter(title__icontains=title)
if category_id != 0:
newses = newses.filter(category=category_id)
paginator = Paginator(newses, 2)
page_obj = paginator.page(page)
pagination_data = self.get_pagination_data(paginator, page_obj)
context = {
'categories': NewsCategory.objects.all(),
'paginator': paginator,
'page_obj': page_obj,
# 'newses': News.objects.select_related('category', 'author').all()
'newses': page_obj.object_list,
"title": title,
"start": start,
"end": end,
"category_id": category_id,
"url_query": "&"+parse.urlencode({
"start": start,
"end": end,
"title": title,
"category": category_id
})
}
context.update(pagination_data)
return render(request, 'cms/news_list.html', context=context)
def get_pagination_data(self, paginator, page_obj, around_count=2):
current_page = page_obj.number
num_pages = paginator.num_pages
left_has_more = False
right_has_more = +False
if current_page <= around_count + 2:
# l_start = 1
left_pages = range(1, current_page)
else:
# l_start = current_page - around_count
left_has_more = True
left_pages = range(current_page - around_count, current_page)
# l_end = current_page
if current_page >= num_pages - around_count - 1:
right_pages = range(current_page + 1, num_pages + 1)
# left_pages = range(l_start, l_end)
else:
right_has_more = True
right_pages = range(current_page + 1, current_page + around_count + 1)
return {
'left_pages': left_pages,
'right_pages': right_pages,
'current_page': current_page,
'left_has_more': left_has_more,
'right_has_more': right_has_more,
'num_pages': num_pages
}