博客项目实践(7)

后台管理

添加路由

urlpatterns = [
    # 后台管理
    path('backend/', views.backend),

    # 添加文章
    path('add/article/', views.add_article),
]

后台展示文章可以分页

添加分页代码

utis文件夹创建mypage.py

# 分页器
class Pagination(object):

    def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
        """
        封装分页相关数据
        :param current_page: 当前页
        :param all_count:    数据库中的数据总条数
        :param per_page_num: 每页显示的数据条数
        :param pager_count:  最多显示的页码个数

        用法:
        queryset = model.objects.all()
        page_obj = Pagination(current_page,all_count)
        page_data = queryset[page_obj.start:page_obj.end]
        获取数据用page_data而不再使用原始的queryset
        获取前端分页样式用page_obj.page_html
        """
        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1

        if current_page < 1:
            current_page = 1

        self.current_page = current_page

        self.all_count = all_count
        self.per_page_num = per_page_num

        # 总页码
        all_pager, tmp = divmod(all_count, per_page_num)
        if tmp:
            all_pager += 1
        self.all_pager = all_pager

        self.pager_count = pager_count
        self.pager_count_half = int((pager_count - 1) / 2)

    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_num

    @property
    def end(self):
        return self.current_page * self.per_page_num

    def page_html(self):
        # 如果总页码 < 11个:
        if self.all_pager <= self.pager_count:
            pager_start = 1
            pager_end = self.all_pager + 1
        # 总页码  > 11
        else:
            # 当前页如果<=页面上最多显示11/2个页码
            if self.current_page <= self.pager_count_half:
                pager_start = 1
                pager_end = self.pager_count + 1

            # 当前页大于5
            else:
                # 页码翻到最后
                if (self.current_page + self.pager_count_half) > self.all_pager:
                    pager_end = self.all_pager + 1
                    pager_start = self.all_pager - self.pager_count + 1
                else:
                    pager_start = self.current_page - self.pager_count_half
                    pager_end = self.current_page + self.pager_count_half + 1

        page_html_list = []
        # 添加前面的nav和ul标签
        page_html_list.append('''
                        <nav aria-label='Page navigation>'
                        <ul class='pagination'>
                    ''')
        first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
        page_html_list.append(first_page)

        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
        else:
            prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)

        page_html_list.append(prev_page)

        for i in range(pager_start, pager_end):
            if i == self.current_page:
                temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
            else:
                temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
            page_html_list.append(temp)

        if self.current_page >= self.all_pager:
            next_page = '<li class="disabled"><a href="#">下一页</a></li>'
        else:
            next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
        page_html_list.append(next_page)

        last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
        page_html_list.append(last_page)
        # 尾部添加标签
        page_html_list.append('''
                                               </nav>
                                               </ul>
                                           ''')
        return ''.join(page_html_list)

后台管理页视图

1 from utils.mypage import Pagination
2 @login_required
3 def backend(request):
4     article_list = models.Article.objects.filter(blog=request.user.blog)
5     page_obj = Pagination(current_page=request.GET.get('page', 1), all_count=article_list.count(), per_page_num=20)
6     page_queryset = article_list[page_obj.start:page_obj.end]
7     return render(request, 'backend/backend.html', locals())

后台管理模板html文件

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>Title</title>
  6     <meta name="keywords" content="width=device-width, initial-scale=1">
  7     <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
  8     <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
  9     <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
 10 </head>
 11 <body>
 12 
 13 <nav class="navbar navbar-inverse">
 14     <div class="container-fluid">
 15         <!-- Brand and toggle get grouped for better mobile display -->
 16         <div class="navbar-header">
 17             <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
 18                     data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
 19                 <span class="sr-only">Toggle navigation</span>
 20                 <span class="icon-bar"></span>
 21                 <span class="icon-bar"></span>
 22                 <span class="icon-bar"></span>
 23             </button>
 24             <a class="navbar-brand" href="/home/">{{ request.user.blog.site_title }}</a>
 25         </div>
 26 
 27         <!-- Collect the nav links, forms, and other content for toggling -->
 28         <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
 29             <ul class="nav navbar-nav">
 30                 <li class="active"><a href="/home/">博客 <span class="sr-only">(current)</span></a></li>
 31                 <li><a href="#">文章</a></li>
 32                 <li class="dropdown">
 33                     <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
 34                        aria-expanded="false">更多 <span class="caret"></span></a>
 35                     <ul class="dropdown-menu">
 36                         <li><a href="#">Action</a></li>
 37                         <li><a href="#">Another action</a></li>
 38                         <li><a href="#">Something else here</a></li>
 39                         <li role="separator" class="divider"></li>
 40                         <li><a href="#">Separated link</a></li>
 41                         <li role="separator" class="divider"></li>
 42                         <li><a href="#">One more separated link</a></li>
 43                     </ul>
 44                 </li>
 45             </ul>
 46             <form class="navbar-form navbar-left">
 47                 <div class="form-group">
 48                     <input type="text" class="form-control" placeholder="Search">
 49                 </div>
 50                 <button type="submit" class="btn btn-default">Submit</button>
 51             </form>
 52             <ul class="nav navbar-nav navbar-right">
 53                 {% if request.user.is_authenticated %}
 54                     <li><a href="#">{{ request.user.username }}</a></li>
 55                     <li class="dropdown">
 56                         <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
 57                            aria-expanded="false">更多操作 <span class="caret"></span></a>
 58                         <ul class="dropdown-menu">
 59                             <li><a href="#" data-toggle="modal" data-target=".bs-example-modal-lg">修改密码</a></li>
 60                             <li><a href="#">修改头像</a></li>
 61                             <li><a href="/{{ request.user }}/">我的博客</a></li>
 62                             <li><a href="/backend/">后台管理</a></li>
 63                             <li role="separator" class="divider"></li>
 64                             <li><a href="{% url 'logout' %}">退出登录</a></li>
 65                         </ul>
 66 
 67                         <div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog"
 68                              aria-labelledby="myLargeModalLabel">
 69                             <div class="modal-dialog modal-lg" role="document">
 70                                 <div class="modal-content">
 71                                     <h1 class="text-center">修改密码</h1>
 72                                     <div class="row">
 73                                         <div class="col-md-8 col-md-offset-2">
 74                                             <div class="form-group">
 75                                                 <label for="">用户名</label>
 76                                                 <input type="text" disabled value="{{ request.user.username }}"
 77                                                        class="form-control">
 78                                             </div>
 79                                             <div class="form-group">
 80                                                 <label for="">原密码</label>
 81                                                 <input type="password" id="id_old_password" class="form-control">
 82                                             </div>
 83                                             <div class="form-group">
 84                                                 <label for="">新密码</label>
 85                                                 <input type="password" id="id_new_password" class="form-control">
 86                                             </div>
 87                                             <div class="form-group">
 88                                                 <label for="">确认密码</label>
 89                                                 <input type="password" id="id_confirm_password" class="form-control">
 90                                             </div>
 91                                             <div class="modal-footer">
 92                                                 <button type="button" class="btn btn-default" data-dismiss="modal">关闭
 93                                                 </button>
 94                                                 <button type="button" class="btn btn-primary" id="id_edit">确认</button>
 95                                                 <span style="color: red" id="password_error"></span>
 96                                             </div>
 97                                             <br>
 98                                             <br>
 99                                         </div>
100                                     </div>
101                                 </div>
102                             </div>
103                         </div>
104                     </li>
105                 {% else %}
106                     <li><a href="{% url 'reg' %}">注册</a></li>
107                     <li><a href="{% url 'login' %}">登录</a></li>
108                 {% endif %}
109             </ul>
110         </div><!-- /.navbar-collapse -->
111     </div><!-- /.container-fluid -->
112 </nav>
113 
114 <div class="container-fluid">
115     <div class="row">
116         <div class="col-md-2">
117             <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
118                 <div class="panel panel-default">
119                     <div class="panel-heading" role="tab" id="headingOne">
120                         <h4 class="panel-title">
121                             <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne"
122                                aria-expanded="true" aria-controls="collapseOne">
123                                 更多操作
124                             </a>
125                         </h4>
126                     </div>
127                     <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel"
128                          aria-labelledby="headingOne">
129                         <div class="panel-body">
130                             <a href="/add/article/">添加文章</a>
131                         </div>
132                     </div>
133                     <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel"
134                          aria-labelledby="headingOne">
135                         <div class="panel-body">
136                             <a href="#">添加随笔</a>
137                         </div>
138                     </div>
139                     <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel"
140                          aria-labelledby="headingOne">
141                         <div class="panel-body">
142                             <a href="#">草稿箱</a>
143                         </div>
144                     </div>
145                     <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel"
146                          aria-labelledby="headingOne">
147                         <div class="panel-body">
148                             <a href="#">其他</a>
149                         </div>
150                     </div>
151                 </div>
152             </div>
153 
154         </div>
155         <div class="col-md-10">
156             <div>
157 
158                 <!-- Nav tabs -->
159                 <ul class="nav nav-tabs" role="tablist">
160                     <li role="presentation" class="active"><a href="#home" aria-controls="home" role="tab" data-toggle="tab">文章</a></li>
161                     <li role="presentation"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">随笔</a></li>
162                     <li role="presentation"><a href="#messages" aria-controls="messages" role="tab" data-toggle="tab">草稿</a></li>
163                     <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">设置</a></li>
164                 </ul>
165 
166                 <!-- Tab panes -->
167                 <div class="tab-content">
168                     <div role="tabpanel" class="tab-pane active" id="home">
169                         {% block article %}
170 
171                         {% endblock %}
172                     </div>
173                     <div role="tabpanel" class="tab-pane" id="profile">随笔页面</div>
174                     <div role="tabpanel" class="tab-pane" id="messages">草稿页面</div>
175                     <div role="tabpanel" class="tab-pane" id="settings">设置页面</div>
176                 </div>
177 
178             </div>
179         </div>
180     </div>
181 </div>
182 
183 {% block js %}
184 
185 {% endblock %}
186 
187 </body>
188 </html>

后台管理页

 1 {% extends 'backend/base.html' %}
 2 
 3 
 4 {% block article %}
 5 {#    接受当前用户所有的文章#}
 6     <table class="table table-hover table-striped">
 7         <thead>
 8         <tr>
 9             <th>标题</th>
10             <th>评论数</th>
11             <th>点赞数</th>
12             <th>操作</th>
13             <th>操作</th>
14         </tr>
15         </thead>
16         <tbody>
17         {% for article in page_queryset %}
18             <tr>
19                 <td><a href="/{{ request.user.username }}/article/{{ article.id }}/">{{ article.title }}</a></td>
20                 <td>{{ article.comment_num }}</td>
21                 <td>{{ article.up_num }}</td>
22                 <td><a href="#">编辑</a></td>
23                 <td><a href="#">删除</a></td>
24             </tr>
25         {% endfor %}
26         </tbody>
27     </table>
28     <div class="pull-right">
29     {{ page_obj.page_html|safe }}
30     </div>
31 {% endblock %}

 

上一篇:聊聊gost的Pager


下一篇:7.4 QtabWidget多页面切换视图