后台管理页面搭建
""" 当一个文件夹下文件比较多的时候 你还可以继续创建文件夹分类处理 templates文件夹 backend文件夹 应用1文件夹 应用2文件夹
bbs后天管理页面用到了分页器
在app01应用下创建utils文件夹,在该文件夹下创建mypage.py文件 """
<body> <!--此处为导航条的html代码--> <div class="container-fluid"> <div class="row"> <div class="col-xs-2"> <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> <div class="panel panel-default"> <div class="panel-heading" role="tab" id="headingOne"> <h4 class="panel-title"> <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne"> 博客后台 </a> </h4> </div> <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <a href="">添加文章</a> </div> </div> <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <a href="">添加随笔</a> </div> </div> <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <a href="">添加文件</a> </div> </div> <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <a href="">更多设置</a> </div> </div> </div> </div> </div> <div class="col-xs-10"> <div> <!-- Nav tabs --> <ul class="nav nav-tabs" role="tablist"> <li role="presentation" class="active"><a href="#home" aria-controls="home" role="tab" data-toggle="tab">文章</a></li> <li role="presentation"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">随笔</a></li> <li role="presentation"><a href="#messages" aria-controls="messages" role="tab" data-toggle="tab">文件</a></li> <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">设置</a></li> </ul> <!-- Tab panes --> <div class="tab-content"> <div role="tabpanel" class="tab-pane active" id="home"> {% block article %} 文章界面 {% endblock %} </div> <div role="tabpanel" class="tab-pane" id="profile"> {% block suibi %} 随笔界面 {% endblock %} </div> <div role="tabpanel" class="tab-pane" id="messages"> {% block file %} 文件界面 {% endblock %} </div> <div role="tabpanel" class="tab-pane" id="settings"> {% block set %} 设置界面 {% endblock %} </div> </div> </div> </div> </div> </div> {% block js %} {% endblock %} </body>backend_base.html
from django.contrib import admin from django.urls import path,re_path from app01 import views from django.views.static import serve from BBS import settings urlpatterns = [ path('admin/', admin.site.urls), # 后台管理 re_path(r'^backend/', views.backend), ]urls.py
class Pagination(object): def __init__(self, current_page, all_count, per_page_num=10, pager_count=11): """ 封装分页相关数据 :param current_page: 当前页 :param all_count: 数据库中的数据总条数 :param per_page_num: 每页显示的数据条数 :param pager_count: 最多显示的页码个数 """ 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)mypage.py
from app01.utils.mypage import Pagination @login_required def backend(request): # 获取当前用户对象所有的文章展示到页面 article_list = models.Article.objects.filter(blog=request.user.blog) # 分页器 page_obj = Pagination(current_page=request.GET.get('page', 1), all_count=article_list.count()) page_queryset = article_list[page_obj.start:page_obj.end] return render(request,'backend/backend.html',locals())views.py
{% extends 'backend/backend_base.html' %} {% block article %} {# 展示当前用户所有的文章#} {# 标题 点赞数 评论数 操作 操作#} <table class="table table-hover table-striped"> <thead> <tr> <th>标题</th> <th>点赞数</th> <th>评论数</th> <th>操作</th> <th>操作</th> </tr> </thead> <tbody> {% for article in article_list %} <tr> <td><a href="/{{ article.blog.userinfo.username }}/article/{{ article.pk }}/">{{ article.title }}</a> </td> <td>{{ article.up_num }}</td> <td>{{ article.comment_num }}</td> <td><a href="">编辑</a></td> <td><a href="">删除</a></td> </tr> {% endfor %} </tbody> </table> <div class="pull-right"> {{ page_obj.page_html|safe }} </div> {% endblock %}backend/backend.html
添加文章功能初步实现
运用到kindeditor(富文本编辑器)
from django.contrib import admin from django.urls import path,re_path from app01 import views from django.views.static import serve from BBS import settings urlpatterns = [ path('admin/', admin.site.urls), # 添加文章 re_path(r'^add/article/',views.add_article), ]urls.py
{% extends 'backend/backend_base.html' %} {% block article %} <h3>添加文章</h3> {# 直接利用form表单提交数据#} <form action="" method="post"> {% csrf_token %} <p>标题</p> <div> <input type="text" name="title" class="form-control"> </div> <p>内容</p> <div> <textarea name="content" id="id_content" cols="30" rows="10"></textarea> </div> <p>分类</p> <div> {% for category in category_list %} <input type="radio" value="{{ category.pk }}" name="category">{{ category.name }} {% endfor %} </div> <p>标签</p> <div> {% for tag in tag_list %} <input type="checkbox" value="{{ tag.pk }}" name="tag">{{ tag.name }} {% endfor %} </div> <input type="submit" class="btn btn-danger"> </form> {% endblock %} {% block js %} {% load static %} <script charset="utf-8" src="{% static 'kindeditor/kindeditor-all-min.js' %}"></script> <script> KindEditor.ready(function (K) { window.editor = K.create('#id_content',{ width:'100%', height:'600px', resizeType:1 }); }); </script> {% endblock %}backend/add_article.html
@login_required def add_article(request): if request.method == 'POST': title = request.POST.get('title') content = request.POST.get('content') category_id = request.POST.get('category') tag_id_list = request.POST.get('tag') # 文章简介 # 1.先简单暴力的直接切取content 150个字符 desc = content[0:150] article_obj = models.Article.objects.create( title=title, content=content, category_id=category_id, desc=desc, blog=request.user.blog ) # 文章和标签的关系表 是我们自己创建的 没法使用add set remove clear方法 # 自己去操作关系表 一次性可能需要创建多条数据 批量插入bulk_create() article_obj_list = [] for i in tag_id_list: tag_article_obj = models.ArticleAndTag(article=article_obj, tag_id=i) article_obj_list.append(tag_article_obj) # 批量插入数据 models.ArticleAndTag.objects.bulk_create(article_obj_list) # 跳转到后台管理文章展示页 return redirect('/backend/') category_list = models.Category.objects.filter(blog=request.user.blog) tag_list = models.Tag.objects.filter(blog=request.user.blog) return render(request, 'backend/add_article.html', locals())views.py
需要注意的问题
# 两个需要注意的问题 1.文章的简介 不能直接切去,应该先获取到当前页面的文本内容之后截取150个文本字符 2.xss攻击 用户直接编写html代码的网站,针对用户直接书写script标签 1.注释标签内部的内容 2.直接将script删除 # 如何解决 # 自己书写代码解决 针对问题一:后端通过正则表达式筛选 针对问题二:需要获取script标签 # 通过对应的模块来解决 beautifulsoup模块(又称bs4模块) 专门用来处理html页面的内容(该模块主要用于爬虫程序) pip3 install beautifulsoup4 # 模块使用 soup = BeautifulSoup(content,'html.parser') tags = soup.find_all() # 获取所有的标签 for tag in tags: # print(tag.name) # 获取页面所有的标签 # 针对script标签 直接删除 if tag.name == 'script': # 删除标签 tag.decompose() # 文章简介 # 1 先简单暴力的直接切去content 150个字符 # desc = content[0:150] # 2 截取文本150个 desc = soup.text[0:150] """ 当你发现一个数据处理起来不是很方便的时候 可以考虑百度搜搜有没有现成的模块帮你完成相应的功能 """
from bs4 import BeautifulSoup @login_required def add_article(request): if request.method == 'POST': title = request.POST.get('title') content = request.POST.get('content') category_id = request.POST.get('category') tag_id_list = request.POST.get('tag') # 模块使用 soup = BeautifulSoup(content,'html.parser') tags = soup.find_all() # print(tags) # 返回的是文章内容的HTML代码 # 获取所有的标签 for tag in tags: # print(tag.name) # 获取页面所有的标签 # 针对script标签,直接删除 if tag.name == 'script': # 删除标签 tag.decompose() # 文章简介 # 1.先简单暴力的直接切去content 150个字符 # desc = content[0:150] # 2.截取文本150个 desc = soup.text[0:150] article_obj = models.Article.objects.create( title=title, content=str(soup), category_id=category_id, desc=desc, blog=request.user.blog ) # 文章和标签的关系表 是我们自己创建的 没法使用add set remove clear方法 # 自己去操作关系表 一次性可能需要创建多条数据 批量插入bulk_create() article_obj_list = [] for i in tag_id_list: tag_article_obj = models.ArticleAndTag(article=article_obj, tag_id=i) article_obj_list.append(tag_article_obj) # 批量插入数据 models.ArticleAndTag.objects.bulk_create(article_obj_list) # 跳转到后台管理文章展示页 return redirect('/backend/') category_list = models.Category.objects.filter(blog=request.user.blog) tag_list = models.Tag.objects.filter(blog=request.user.blog) return render(request, 'backend/add_article.html', locals())views.py
标签:功能,管理,self,list,tag,后台,article,pager,page From: https://www.cnblogs.com/yuanxiaojiang/p/17371283.html