大家好,这是皮爷给大家带来的最新的学习Python能干啥?之Django教程,从零开始,到最后成功部署上线的项目。这一节,我们来优化文章的管理功能,包括发布,查看,修改和删除。
上一节我们负责开发了文章管理系统,即文章的增删改查,虽然说文章做的和Category还有Tag一样,但是我们在实际开发的过程中,确实感受到了文章确实要更加复杂一些,所以我们这里就需要优化一下文章的管理页面,让他更加的美观,合理。
需求分析
为啥要优化文章的管理页面?
- 文章数量肯定很多;
- 文章结构比较复杂;
- 每次修改的时候,都要点进修改页面,效率低;
优化功能
针对以上的需求,我们可以优化的点:
- 表格的显示内容可以优化一下;
- 加入分页逻辑;
- 删除逻辑不再是直接删除,而是将Post的状态修改为删除。
我们可以将表格的内容从原来的ID,标题,时间,操作修改为:ID,标题,分类,时间,状态,操作。
所以,我们的manage.html页面的table结构就应该变成:
<table class="table table-bordered table-hover">
<thead class="thead-light">
<tr>
<th style="width: 10%;">#</th>
<th>Post_Title</th>
<th style="width: 20%;">Post_Category</th>
<th style="width: 15%;">Post_Show_Time</th>
<th style="width: 10%;">Post_Status</th>
<th style="width: 15%;">actions</th>
</tr>
</thead>
<tbody>
{% for item in list_data %}
<tr>
<td>{{ item.id }}</td>
<td><a href="{% url 'cms:post_edit' %}?post_id={{ item.id }}"
class="">{{ item.title }}</a></td>
<td>{{ item.category.name }}</td>
<td>{{ item.publish_time_show | datapicker_format }}</td>
<td>
{% for list_item in list_data_status %}
{% if item.status == list_item.0 %}
{{ list_item.1 }}
{% endif %}
{% endfor %}
</td>
<td>
<a href="{% url 'cms:post_edit' %}?post_id={{ item.id }}"
class="btn btn-info btn-xs">Modify</a>
<button class="btn btn-danger btn-xs delete-btn"
data-post-id="{{ item.id }}">
Delete
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
修改完的表格会长这个样子:
接着我们修改一下Delete的逻辑。之前我们的删除逻辑是:直接在数据库里面找到对应id的文章,然后执行delete()方法。这样的做法会将数据直接从数据库里面删除,我们的优化方法,是应该找到对应id的文章,然后将它的status设置成delete即可,并不需要从数据库里面删除他。
所以,我们只需要将原来的PostDeleteView修改一下即可:
class PostDeleteView(View):
def post(self, request):
post_id = request.POST.get('post_id')
Post.objects.filter(id=post_id).update(status=Post.STATUS_DELETE)
return restful.ok()
最后就是要加入分页逻辑,因为将来文章肯定会很多,我们一下子展示那么多内容,会显得很慢,所以我们引入Paginator。
具体的做法就是在我们之前的post_manage_view()
函数中,添加Paginator。首先在settings.py里面配置一下一页显示的数据:
ONE_PAGE_NEWS_COUNT=10
然后将post_manage_view()
函数修改:
def post_manage_view(request):
page = int(request.GET.get('p', 1))
posts = Post.objects.all()
paginator = Paginator(posts, settings.ONE_PAGE_NEWS_COUNT)
page_obj = paginator.page(page)
context = {
"list_data": posts,
'list_data_status': Post.STATUS_ITEMS
}
context_data = get_pagination_data(paginator, page_obj)
context.update(context_data)
return render(request, 'cms/post/manage.html', context=context)
def get_pagination_data(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 + settings.ONE_PAGE_NEWS_COUNT:
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': left_pages,
# right_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
}
可以看到,我们新增了很多数据要传送给前端,所以,我们还要在前端的Table最下面,加入Page:
<div class="row">
<div class="col-sm-5">
<p class="pull-left">第{{ current_page }}页/总共{{ num_pages }}页</p>
</div>
<div class="col-sm-7">
<div class="dataTables_paginate paging_simple_numbers float-right">
<ul class="pagination">
{#上一页#}
{% if page_obj.has_previous %}
<li class="paginate_button page-item "><a class="page-link" href="?p=
{{ page_obj.previous_page_number }}{{ url_query }}">上一页</a></li>
{% else %}
<li class="paginate_button page-item previous disabled"><a
class="page-link"
href="javascript:void(0);">上一页</a>
</li>
{% endif %}
{# 是否需要出现三个点 #}
{% if left_has_more %}
<li class="paginate_button page-item "><a class="page-link" href="?p=1">1</a>
</li>
<li class="paginate_button page-item "><a class="page-link"
href="javascript:void(0);">...</a>
</li>
{% endif %}
{# 左边的页码 #}
{% for left_page in left_pages %}
<li class="paginate_button page-item "><a class="page-link" href="?p=
{{ left_page }}{{ url_query }}">{{ left_page }}</a></li>
{% endfor %}
{# 当前的页面 #}
<li class="paginate_button page-item active"><a class="page-link" href="?p=
{{ current_page }}{{ url_query }}">{{ current_page }}</a></li>
{# 右边的页码 #}
{% for right_page in right_pages %}
<li class="paginate_button page-item "><a class="page-link" href="?p=
{{ right_page }}{{ url_query }}">{{ right_page }}</a></li>
{% endfor %}
{# 用来控制右边三个点 #}
{% if right_has_more %}
<li class="paginate_button page-item "><a class="page-link"
href="javascript:void(0);">...</a>
</li>
<li class="paginate_button page-item "><a class="page-link" href="?p=
{{ num_pages }}{{ url_query }}">{{ num_pages }}</a></li>
{% endif %}
{#下一页#}
{% if page_obj.has_next %}
<li class="paginate_button page-item next"><a class="page-link" href="?p=
{{ page_obj.next_page_number }}{{ url_query }}">下一页</a></li>
{% else %}
<li class="paginate_button page-item next disabled"><a class="page-link"
href="javascript:void(0);">下一页</a>
</li>
{% endif %}
</ul>
</div>
</div>
</div>
这么多代码,其实逻辑也不简单,但是日后如果大家想要用,就直接拿去用就好。这些已经是轮子了,既然是轮子,就拿去直接用。
最后,我们来看一下我们的效果,在页面我们看到这篇文章的状态是正常:
我们点击一下Delete按钮:
发现文章的状态成了删除,而且底部Page什么的都正常,Tabel显示结构也很合理,所以我们的优化很成功。
技术总结
最后总结一下,
优化结构:
1.增加了分页逻辑,分页逻辑就是在修改原有post_manage_view
函数的基础外加html修改用来支撑功能;
2. Table的从新布局;
3. 修改删除逻辑,让文章不再直接从数据库删除,而是将文章的Status直接设置成删除状态即可;
4. 完毕。
整套教程源码获取,可以关注『皮爷撸码』,回复『peekpa.com』
长按下图二维码关注,如文章对你有启发,欢迎在看与转发。