1:后台设置
1.1 设置后台路由 url
from django.conf.urls import url from django.conf.urls import include from .views import user urlpatterns = [ url(r'^index.html$', user.index), url(r'article-(?P<ms_Type>d+)-(?P<classification_id>d+).html$', user.article, name='article'), ]
1.2 设置布局页面
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> <link rel="stylesheet" href="/static/plugins/font-awesome-4.7.0/css/font-awesome.min.css"/> <link rel="stylesheet" href="/static/css/common.css"/> <link rel="stylesheet" href="/static/css/backend.css"/> {% block css %} {% endblock %} </head> <body> <div class="pg-header"> <div class="logo left" style="text-align: center;background-color: #1c5a9c;"> <a href="#" style="color: #ffffff;font-size:30px;font-weight: bold;text-decoration: none"> 后台管理 </a> </div> <div class="left-menu left"> <a class="menu-item" href="/">博客首页</a> </div> <div class="right-menu right clearfix"> <div class="user-info right"> <a href="#" class="avatar"> <img class="img-circle" src="/static/imgs/avatar/default.png"> </a> <div class="more-info"> <a href="#" class="more-item">个人信息</a> <a href="/logout.html" class="more-item">注销</a> </div> </div> <a class="user-menu right"> 消息 <i class="fa fa-commenting-o" aria-hidden="true"></i> <span class="badge bg-success">2</span> </a> <a class="user-menu right"> 通知 <i class="fa fa-envelope-o" aria-hidden="true"></i> <span class="badge bg-success">2</span> </a> <a class="user-menu right"> 任务 <i class="fa fa-bell-o" aria-hidden="true"></i> <span class="badge bg-danger">4</span> </a> </div> </div> <div class="pg-body"> <div class="menu"> <a class="menu-item" href="/backend/article-0-0.html"> <i class="fa fa-cogs" aria-hidden="true"></i> <span>文章管理</span> </a> <a class="menu-item" href="/backend/category.html"> <i class="fa fa-cogs" aria-hidden="true"></i> <span>分类管理</span> </a> <a class="menu-item" href="/backend/tag.html"> <i class="fa fa-cogs" aria-hidden="true"></i> <span>标签管理</span> </a> <a class="menu-item" href="/backend/base-info.html"> <i class="fa fa-cogs" aria-hidden="true"></i> <span>个人信息</span> </a> </div> <div class="content"> {% block conent %} {% endblock %} </div> </div> <script type="text/javascript" src="/static/js/jquery-3.3.1.min.js"></script> {% block js %}{% endblock %} </body> </html>
1.3 设置首页
{% extends 'Backend/backend_layout.html' %} {% block css %} {% endblock %} {% block conent %} <h1>欢迎登陆:{{ request.session.user_info.username }}</h1> {% endblock %} {% block js %} {% endblock %}
由路由可知,调用后台的user.py中的index方法
from django.shortcuts import render from repository import models from web.Views.Tools import AaronPager from web.Views.Tools.pagination import Pagination from django.urls import reverse def index(request): return render(request, 'Backend/backend_index.html')
2 文章管理
2.1 文章管理之页面展示
{% extends 'Backend/backend_layout.html' %} {% load search %} {% block css %} <style> .conditions a{ display: inline-block; padding: 2px 5px; margin-left: 5px; } .conditions a.active{ background-color: #b35215; color: #ffffff; } </style> {% endblock %} {% block conent %} <ol class="breadcrumb" style="margin-bottom: 0;"> <li><a href="#">文章管理</a></li> <li class="active">文章列表</li> </ol> <div> <div style="border: 1px dashed #dddddd;padding: 8px;border-left: 3px solid #337ab7;"> <i class="fa fa-search" aria-hidden="true"></i> 搜索条件 </div> <div style="padding: 10px"> <div class="conditions row clearfix" style="margin: 0;padding: 8px 0;"> <div class="col-xs-1" style="text-align: right"> {% category_all arg_dict %} </div> <div class="col-xs-11"> {% category_combine category_list arg_dict %} </div> </div> <div class="conditions row clearfix" style="margin: 0;padding: 8px 0;"> <div class="col-xs-1" style="text-align: right"> {% article_type_all arg_dict %} </div> <div class="col-xs-11"> {% article_type_combine type_list arg_dict %} </div> </div> </div> <div class="clearfix" style="height: 36px;line-height: 35px;padding: 0 15px;border-top: 1px solid #dddddd;background-color: #f1f0f0"> <i class="fa fa-table" aria-hidden="true"></i> 搜索文章({{ data_count }}篇) <a target="_blank" href="/backend/add-article.html" class="right" style="display: inline-block;padding:0 10px;background-color: #428bca;color: #ffffff;"> <i class="fa fa-plus-circle" aria-hidden="true"></i> 创建新文章 </a> </div> <table class="table table-bordered"> <thead> <tr> <th>文章标题</th> <th>操作</th> </tr> </thead> <tbody> {% for row in result %} <tr nid="{{ row.nid }}"> <td><a href="/{{ row.blog.site }}/{{ row.nid }}.html">{{ row.title }}</a></td> <td> <a class="btn btn-danger btn-xs"> <i class="fa fa-times" aria-hidden="true"></i> 删除 </a> | <a class="btn btn-primary btn-xs" href="/backend/edit-article-{{ row.nid }}.html"> <i class="fa fa-pencil-square-o" aria-hidden="true"></i> 编辑 </a> </td> </tr> {% endfor %} </tbody> </table> <div class="clearfix"> <ul class="pagination right" style="margin-top: 0"> {{ page_str }} </ul> </div> </div> {% endblock %} {% block js %} {% endblock %}
from django.shortcuts import render from repository import models from web.Views.Tools import AaronPager from web.Views.Tools.pagination import Pagination from django.urls import reverse def index(request): return render(request, 'Backend/backend_index.html') def article(request, *args, **kwargs): """ 博主个人文章管理 :param request: :return: """ # 通过session拿掉用户的登录信息 blog_id = request.session['user_info']['bloginfo__bid'] condition = {} # 遍历kwargs条件(ms_Type、classification_id) for k, v in kwargs.items(): if v == '0': pass else: condition[k] = v condition['blog_id'] = blog_id # 筛选出文章总数 data_count = models.Article.objects.filter(**condition).count() # 获取页数 page = Pagination(request.GET.get('p', 1), data_count) # 筛选出文章列表 result = models.Article.objects.filter(**condition).order_by('-nid').only('nid', 'title','blog').select_related('blog')[page.start:page.end] #通过通用方法,生成分页 page_str = page.page_str(reverse('article', kwargs=kwargs)) #获取分类内容 category_list = models.Classification.objects.filter(blog_id=blog_id).values('nid', 'title') # 获取类型内容 type_list = map(lambda item: {'nid': item[0], 'title': item[1]}, models.Article.masterStation_type) kwargs['p'] = page.current_page return render(request, 'Backend/backend_article.html', {'result': result, 'page_str': page_str, 'category_list': category_list, 'type_list': type_list, 'arg_dict': kwargs, 'data_count': data_count } )
其中涉及到一个分页的帮助类
__author__ = 'Administrator' from django.utils.safestring import mark_safe # 分页组件 class Pagination(object): # 当前页码、总数、每页显示条数、显示页码范围 def __init__(self, current_page, data_count, per_page_count=10, pager_num=7): try: self.current_page = int(current_page) except Exception as e: self.current_page = 1 self.data_count = data_count self.per_page_count = per_page_count self.pager_num = pager_num @property def start(self): return (self.current_page - 1) * self.per_page_count @property def end(self): return self.current_page * self.per_page_count # 计算总页数 @property def total_count(self): v, y = divmod(self.data_count, self.per_page_count) if y: v += 1 return v # 返回页码的字符串 def page_str(self, base_url): page_list = [] # 总页数小于页码范围 if self.total_count < self.pager_num: start_index = 1 end_index = self.total_count + 1 else: if self.current_page <= (self.pager_num + 1) / 2: start_index = 1 end_index = self.pager_num + 1 else: start_index = self.current_page - (self.pager_num - 1) / 2 end_index = self.current_page + (self.pager_num + 1) / 2 if (self.current_page + (self.pager_num - 1) / 2) > self.total_count: end_index = self.total_count + 1 start_index = self.total_count - self.pager_num + 1 if self.current_page == 1: prev = '<li><a class="page" href="javascript:void(0);">上一页</a></li>' else: prev = '<li><a class="page" href="%s?p=%s">上一页</a></li>' % (base_url, self.current_page - 1,) page_list.append(prev) for i in range(int(start_index), int(end_index)): if i == self.current_page: temp = '<li class="active"><a class="page active" href="%s?p=%s">%s</a></li>' % (base_url, i, i) else: temp = '<li><a class="page" href="%s?p=%s">%s</a></li>' % (base_url, i, i) page_list.append(temp) if self.current_page == self.total_count: nex = '<li><a class="page" href="javascript:void(0);">下一页</a></li>' else: nex = '<li><a class="page" href="%s?p=%s">下一页</a></li>' % (base_url, self.current_page + 1,) page_list.append(nex) page_str = mark_safe("".join(page_list)) return page_str
2.2 文章管理之新增
2.2.1 设置url
urlpatterns = [ url(r'^index.html$', user.index), url(r'article-(?P<ms_Type>d+)-(?P<classification_id>d+).html$', user.article, name='article'), url(r'^add-article.html$',user.add_article), #创建文章路由 ]
2.2.2 创建一个form类用于前台页面和后台之间,进行数据传递
# 引入文件 from django import forms from django.forms import fields from django.forms import widgets from repository import models class ArticleForm(forms.Form): title = forms.CharField( widget=widgets.TextInput(attrs={'class': 'form-control', 'placeholder': '文章标题'}) ) summary = forms.CharField( widget=widgets.Textarea(attrs={'class':'form-control','placeholder':'文章简介','rows':'3'}) ) content = forms.CharField( widget=widgets.Textarea(attrs={'class': 'kind-content'}) ) # 单选按钮(定义的枚举) ms_Type = forms.IntegerField( widget=widgets.RadioSelect(choices=models.Article.masterStation_type) ) # 分类 classification_id=forms.ChoiceField( choices=[], widget=widgets.RadioSelect ) # 标签 tags=forms.MultipleChoiceField( choices=[], widget=widgets.CheckboxSelectMultiple ) def __init__(self,request,*args,**kwargs): super(ArticleForm,self).__init__(*args,**kwargs) blog_id=request.session['user_info']["bloginfo__bid"] self.fields['classification_id'].choices=models.Classification.objects.filter(blog_id=blog_id).values_list('nid','title') self.fields['tags'].choices=models.Tag.objects.filter(blog_id=blog_id).values_list('nid','title')
2.2.3 创建前台页面
{% extends 'Backend/backend_layout.html' %} {% load search %} {% block css %} <style> .conditions a{ display: inline-block; padding: 2px 5px; margin-left: 5px; } .conditions a.active{ background-color: #b35215; color: #ffffff; } </style> {% endblock %} {% block conent %} <ol class="breadcrumb" style="margin-bottom: 0;"> <li><a href="#">文章管理</a></li> <li class="active">文章列表</li> </ol> <div> <div style="border: 1px dashed #dddddd;padding: 8px;border-left: 3px solid #337ab7;"> <i class="fa fa-search" aria-hidden="true"></i> 搜索条件 </div> <div style="padding: 10px"> <div class="conditions row clearfix" style="margin: 0;padding: 8px 0;"> <div class="col-xs-1" style="text-align: right"> {% category_all arg_dict %} </div> <div class="col-xs-11"> {% category_combine category_list arg_dict %} </div> </div> <div class="conditions row clearfix" style="margin: 0;padding: 8px 0;"> <div class="col-xs-1" style="text-align: right"> {% article_type_all arg_dict %} </div> <div class="col-xs-11"> {% article_type_combine type_list arg_dict %} </div> </div> </div> <div class="clearfix" style="height: 36px;line-height: 35px;padding: 0 15px;border-top: 1px solid #dddddd;background-color: #f1f0f0"> <i class="fa fa-table" aria-hidden="true"></i> 搜索文章({{ data_count }}篇) <a target="_blank" href="/backend/add-article.html" class="right" style="display: inline-block;padding:0 10px;background-color: #428bca;color: #ffffff;"> <i class="fa fa-plus-circle" aria-hidden="true"></i> 创建新文章 </a> </div> <table class="table table-bordered"> <thead> <tr> <th>文章标题</th> <th>操作</th> </tr> </thead> <tbody> {% for row in result %} <tr nid="{{ row.nid }}"> <td><a href="/{{ row.blog.site }}/{{ row.nid }}.html">{{ row.title }}</a></td> <td> <a class="btn btn-danger btn-xs" href="/backend/del-article-{{ row.nid }}.html"> <i class="fa fa-times" aria-hidden="true"></i> 删除 </a> | <a class="btn btn-primary btn-xs" href="/backend/edit-article-{{ row.nid }}.html"> <i class="fa fa-pencil-square-o" aria-hidden="true"></i> 编辑 </a> </td> </tr> {% endfor %} </tbody> </table> <div class="clearfix"> <ul class="pagination right" style="margin-top: 0"> {{ page_str }} </ul> </div> </div> {% endblock %} {% block js %} {% endblock %}
2.2.4 开发View中的与后台交互逻辑
from django.shortcuts import render,redirect from repository import models from web.Views.Tools import AaronPager from web.Views.Tools.pagination import Pagination from django.urls import reverse from forms.article import ArticleForm #引用form中的文章表单,用于添加、修改文章 from django.db import transaction #引用事务 from utils.xss import XSSFilter #引用Xss安全机制,存储富文本编辑器中内容 from utils.pagination import Pagination import datetime #引入时间模块 def index(request): return render(request, 'Backend/backend_index.html') def article(request, *args, **kwargs): """ 博主个人文章管理 :param request: :return: """ # 通过session拿掉用户的登录信息 blog_id = request.session['user_info']['bloginfo__bid'] condition = {} # 遍历kwargs条件(ms_Type、classification_id) for k, v in kwargs.items(): if v == '0': pass else: condition[k] = v condition['blog_id'] = blog_id # 筛选出文章总数 data_count = models.Article.objects.filter(**condition).count() # 获取页数 page = Pagination(request.GET.get('p', 1), data_count) # 筛选出文章列表 result = models.Article.objects.filter(**condition).order_by('-nid').only('nid', 'title','blog').select_related('blog')[page.start:page.end] #通过通用方法,生成分页 page_str = page.page_str(reverse('article', kwargs=kwargs)) #获取分类内容 category_list = models.Classification.objects.filter(blog_id=blog_id).values('nid', 'title') # 获取类型内容 type_list = map(lambda item: {'nid': item[0], 'title': item[1]}, models.Article.masterStation_type) kwargs['p'] = page.current_page return render(request, 'Backend/backend_article.html', {'result': result, 'page_str': page_str, 'category_list': category_list, 'type_list': type_list, 'arg_dict': kwargs, 'data_count': data_count } ) def add_article(request): # 添加文章 if request.method == "GET": form = ArticleForm(request=request) return render(request,"Backend/add_article.html",{'form':form }) elif request.method=='POST': form = ArticleForm(request=request,data=request.POST) if form.is_valid(): with transaction.atomic(): tags=form.cleaned_data.pop('tags') content = form.cleaned_data.pop('content') content=XSSFilter().process(content) form.cleaned_data['blog_id']=request.session['user_info']["bloginfo__bid"] # 需要将该值转化一下 form.cleaned_data['classification_id']=models.Classification.objects.filter(nid=form.cleaned_data['classification_id']).first() form.cleaned_data['create_time'] = datetime.datetime.now() obj = models.Article.objects.create(**form.cleaned_data) #添加文章 models.Article_Detail.objects.create(detail=content,article_id=obj) #添加文章详细 tag_list=[] for tag_id in tags: tag_id=int(tag_id) tag_list.append(models.Article_Tag(article_id_id=obj.nid,tag_id_id=tag_id)) models.Article_Tag.objects.bulk_create(tag_list) #批量创建,厉害 return redirect("backend/article-0-0.html") else: return render(request, "backend/add_article.html",{'form':form}) else: return redirect('/')
2.3 文章管理之添加状态字段。
我们的删除都是逻辑删除,所以需要添加个状态字段,用于区分(删除、正常)
2.3.1 修改模型中的字段,添加一个status字段属性
2.3.2 修改user.py 中的方法,获取数据时根据状态进行筛选
2.4 文章管理之删除功能
2.4.1 修改前台页面
<a class="btn btn-danger btn-xs" onClick="return confirm('确定删除?');" href="/backend/del-article-{{ row.nid }}.html"> <i class="fa fa-times" aria-hidden="true"></i> 删除 </a>
2.4.2 修改路由
from django.conf.urls import url from django.conf.urls import include from .views import user urlpatterns = [ url(r'^index.html$', user.index), url(r'article-(?P<ms_Type>d+)-(?P<classification_id>d+).html$', user.article, name='article'), url(r'^add-article.html$',user.add_article), #创建文章路由 url(r'^del-article-(?P<nid>d+).html$', user.del_article),#删除文章路由 ]
2.4.3 修改后台View方法
def del_article(request, nid): # 删除文章 blog_id = request.session['user_info']['bloginfo__bid'] nid=int(nid) v=models.Article.objects.filter(blog_id=blog_id,nid=nid).update(status=0) if not v: return HttpResponse('删除失败') return redirect("backend/article-0-0.html")
2.5 文章管理之编辑功能
由于编辑和新增页面相似,我决定使用同一个页面,只不过在传递参数的时候,通过oper字段区分
2.5.1 修改列表页面(主要给编辑按钮添加链接)
{% extends 'Backend/backend_layout.html' %} {% load search %} {% block css %} <style> .conditions a{ display: inline-block; padding: 2px 5px; margin-left: 5px; } .conditions a.active{ background-color: #b35215; color: #ffffff; } </style> {% endblock %} {% block conent %} <ol class="breadcrumb" style="margin-bottom: 0;"> <li><a href="#">文章管理</a></li> <li class="active">文章列表</li> </ol> <div> <div style="border: 1px dashed #dddddd;padding: 8px;border-left: 3px solid #337ab7;"> <i class="fa fa-search" aria-hidden="true"></i> 搜索条件 </div> <div style="padding: 10px"> <div class="conditions row clearfix" style="margin: 0;padding: 8px 0;"> <div class="col-xs-1" style="text-align: right"> {% category_all arg_dict %} </div> <div class="col-xs-11"> {% category_combine category_list arg_dict %} </div> </div> <div class="conditions row clearfix" style="margin: 0;padding: 8px 0;"> <div class="col-xs-1" style="text-align: right"> {% article_type_all arg_dict %} </div> <div class="col-xs-11"> {% article_type_combine type_list arg_dict %} </div> </div> </div> <div class="clearfix" style="height: 36px;line-height: 35px;padding: 0 15px;border-top: 1px solid #dddddd;background-color: #f1f0f0"> <i class="fa fa-table" aria-hidden="true"></i> 搜索文章({{ data_count }}篇) <a target="_blank" href="/backend/add-article.html" class="right" style="display: inline-block;padding:0 10px;background-color: #428bca;color: #ffffff;"> <i class="fa fa-plus-circle" aria-hidden="true"></i> 创建新文章 </a> </div> <table class="table table-bordered"> <thead> <tr> <th>文章标题</th> <th>操作</th> </tr> </thead> <tbody> {% for row in result %} <tr nid="{{ row.nid }}"> <td><a href="/{{ row.blog.site }}/{{ row.nid }}.html">{{ row.title }}</a></td> <td> <a class="btn btn-danger btn-xs" onClick="return confirm('确定删除?');" href="/backend/del-article-{{ row.nid }}.html"> <i class="fa fa-times" aria-hidden="true"></i> 删除 </a> | <a class="btn btn-primary btn-xs" href="/backend/edit-article-{{ row.nid }}.html"> <i class="fa fa-pencil-square-o" aria-hidden="true"></i> 编辑 </a> </td> </tr> {% endfor %} </tbody> </table> <div class="clearfix"> <ul class="pagination right" style="margin-top: 0"> {{ page_str }} </ul> </div> </div> {% endblock %} {% block js %} {% endblock %}
2.5.2 修改路由
from django.conf.urls import url from django.conf.urls import include from .views import user urlpatterns = [ url(r'^index.html$', user.index), url(r'article-(?P<ms_Type>d+)-(?P<classification_id>d+).html$', user.article, name='article'), url(r'^add-article.html$',user.add_article), #创建文章路由 url(r'^del-article-(?P<nid>d+).html$', user.del_article),#删除文章路由 url(r'^edit-article-(?P<nid>d+).html$', user.edit_article),#修改文章路由 ]
2.5.3 修改后台View方法(主要添加编辑功能和完善新增功能
from django.shortcuts import render,redirect,HttpResponse from repository import models from web.Views.Tools import AaronPager from web.Views.Tools.pagination import Pagination from django.urls import reverse from forms.article import ArticleForm #引用form中的文章表单,用于添加、修改文章 from django.db import transaction #引用事务 from utils.xss import XSSFilter #引用Xss安全机制,存储富文本编辑器中内容 from utils.pagination import Pagination import datetime #引入时间模块 def index(request): return render(request, 'Backend/backend_index.html') def article(request, *args, **kwargs): """ 博主个人文章管理 :param request: :return: """ # 通过session拿掉用户的登录信息 blog_id = request.session['user_info']['bloginfo__bid'] condition = {} # 遍历kwargs条件(ms_Type、classification_id) for k, v in kwargs.items(): if v == '0': pass else: condition[k] = v condition['blog_id'] = blog_id condition['status'] =1 # 筛选出文章总数 data_count = models.Article.objects.filter(**condition).count() # 获取页数 page = Pagination(request.GET.get('p', 1), data_count) # 筛选出文章列表 result = models.Article.objects.filter(**condition).order_by('-nid').only('nid', 'title','blog').select_related('blog')[page.start:page.end] #通过通用方法,生成分页 page_str = page.page_str(reverse('article', kwargs=kwargs)) #获取分类内容 category_list = models.Classification.objects.filter(blog_id=blog_id).values('nid', 'title') # 获取类型内容 type_list = map(lambda item: {'nid': item[0], 'title': item[1]}, models.Article.masterStation_type) kwargs['p'] = page.current_page return render(request, 'Backend/backend_article.html', {'result': result, 'page_str': page_str, 'category_list': category_list, 'type_list': type_list, 'arg_dict': kwargs, 'data_count': data_count } ) def add_article(request): # 添加文章 if request.method == "GET": form = ArticleForm(request=request) return render(request,"Backend/add_article.html",{'form':form ,'oper':'add','nid':-1}) elif request.method=='POST': oper=request.GET.get('oper', 'add') nid =int(request.GET.get('nid', -1)) if oper =='add': form = ArticleForm(request=request,data=request.POST) if form.is_valid(): with transaction.atomic(): tags=form.cleaned_data.pop('tags') content = form.cleaned_data.pop('content') content=XSSFilter().process(content) form.cleaned_data['blog_id']=request.session['user_info']["bloginfo__bid"] # 需要将该值转化一下 form.cleaned_data['classification_id']=models.Classification.objects.filter(nid=form.cleaned_data['classification_id']).first() form.cleaned_data['create_time'] = datetime.datetime.now() obj = models.Article.objects.create(**form.cleaned_data) #添加文章 models.Article_Detail.objects.create(detail=content,article_id=obj) #添加文章详细 tag_list=[] for tag_id in tags: tag_id=int(tag_id) tag_list.append(models.Article_Tag(article_id_id=obj.nid,tag_id_id=tag_id)) models.Article_Tag.objects.bulk_create(tag_list) #批量创建,厉害 return redirect("backend/article-0-0.html") else: return render(request, "backend/add_article.html",{'form':form,'oper':'add','nid':-1}) elif oper=="edit" and nid>0: blog_id = request.session['user_info']['bloginfo__bid'] form = ArticleForm(request=request, data=request.POST) if form.is_valid(): obj = models.Article.objects.filter(nid=nid, blog_id=blog_id, status=1).first() if not obj: return HttpResponse('该文章不存在或已删除') with transaction.atomic(): tags = form.cleaned_data.pop('tags') content = form.cleaned_data.pop('content') content = XSSFilter().process(content) form.cleaned_data['blog_id'] = request.session['user_info']["bloginfo__bid"] # 需要将该值转化一下 form.cleaned_data['classification_id'] = models.Classification.objects.filter( nid=form.cleaned_data['classification_id']).first() form.cleaned_data['create_time'] = datetime.datetime.now() obj = models.Article.objects.filter(nid=obj.nid, status=1).update(**form.cleaned_data) # 修改文章 models.Article_Detail.objects.filter(article_id_id=nid, status=1).update(detail=content ) # 修改文章详细 models.Article_Tag.objects.filter(article_id_id=nid).delete() #使用之前,先把该文章下面的所有标签删除 tag_list = [] for tag_id in tags: tag_id = int(tag_id) tag_list.append(models.Article_Tag(article_id_id=nid, tag_id_id=tag_id)) models.Article_Tag.objects.bulk_create(tag_list) # 批量创建,不知道更新的时候是否有问题 return redirect("backend/article-0-0.html") else: return render(request, "backend/add_article.html", {'form': form,'oper':'edit','nid':nid}) else: return redirect('/') else: return redirect('/') def del_article(request, nid): # 删除文章 blog_id = request.session['user_info']['bloginfo__bid'] nid=int(nid) v=models.Article.objects.filter(blog_id=blog_id,nid=nid).update(status=0) if not v: return HttpResponse('删除失败') return redirect("backend/article-0-0.html") def edit_article(request, nid): # 编辑文章 blog_id = request.session['user_info']['bloginfo__bid'] if request.method == "GET": # 查找数据库中该条数据 obj=models.Article.objects.filter(nid=nid,blog_id=blog_id,status=1).first() if not obj: return HttpResponse('该文章不存在或已删除') # 获取该文章的标签 tags=obj.tags.values_list('nid') if tags: tags = list(zip(*tags))[0] init_dict={ 'nid':obj.nid, 'title':obj.title, 'summary':obj.summary, 'content':obj.article_detail.detail if hasattr(obj, 'article_detail') else '', 'ms_Type':obj.ms_Type, 'classification_id':obj.classification_id_id, 'tags': tags } form = ArticleForm(request=request, data=init_dict) # 页面内容一致,可以简化使用新增的页面 return render(request, 'Backend/add_article.html', {'form': form,'oper':'edit','nid':nid}) else: return redirect('/')
2.5.4 修改add页面,主要是post时候给链接添加参数
{% extends 'Backend/backend_layout.html' %} {% block css %} <link rel="stylesheet" href="/static/plugins/kindeditor/themes/default/default.css"/> <style> .kind-content { 100%; min-height: 500px; } </style> {% endblock %} {% block conent %} <ol class="breadcrumb" style="margin-bottom: 0;"> <li><a href="#">文章管理</a></li> <li class="active">文章修改</li> </ol> <div style="padding: 5px 8px;"> <form method="POST" action="/backend/add-article.html?oper={{ oper }}&nid={{ nid }}" novalidate> <div class="form-group"> <label for="{{ form.title.id_for_label }}">标题 <span>{{ form.title.errors.0 }}</span></label> {{ form.title }} </div> <div class="form-group"> <label for="summary">简介 <span>{{ form.summary.errors.0 }}</span></label> {{ form.summary }} </div> <div class="form-group"> <label for="content">内容 <span>{{ form.content.errors.0 }}</span></label> {{ form.content }} </div> <div class="form-group"> <label>类型 <span>{{ form.ms_Type.errors.0 }}</span></label> <div> {{ form.ms_Type }} </div> </div> <div class="form-group"> <label>分类 <span>{{ form.classification_id.errors.0 }}</span></label> <div> {{ form.classification_id }} </div> </div> <div class="form-group"> <label>标签 <span>{{ form.tags.errors.0 }}</span></label> <div> {{ form.tags }} </div> </div> <div class="form-group"> <input type="submit" class="btn btn-primary" value="保 存"> </div> {%csrf_token%} </form> </div> {% endblock %} {% block js %} <script charset="utf-8" src="/static/plugins/kindeditor/kindeditor-all-min.js"></script> <script charset="utf-8" src="/static/plugins/kindeditor/lang/zh-CN.js"></script> <script> KindEditor.ready(function (K) { var editor = K.create('textarea[name="content"]', { resizeType: 1 }); }); </script> {% endblock %}
2.6 根据标题名称查询(缺陷,无法分页)
这个其实没什么,只是通过get把查询关键字传递过来,然后进行条件筛选
{% extends 'Backend/backend_layout.html' %} {% load search %} {% block css %} <style> .conditions a{ display: inline-block; padding: 2px 5px; margin-left: 5px; } .conditions a.active{ background-color: #b35215; color: #ffffff; } </style> {% endblock %} {% block conent %} <ol class="breadcrumb" style="margin-bottom: 0;"> <li><a href="#">文章管理</a></li> <li class="active">文章列表</li> </ol> <div> <div style="border: 1px dashed #dddddd;padding: 8px;border-left: 3px solid #337ab7;"> <input type="text" id="keyWord" name="keyWord" value="{{ keyWord }}" > <i class="fa fa-search" aria-hidden="true" onclick="search()"></i> 搜索条件 </div> <div style="padding: 10px"> <div class="conditions row clearfix" style="margin: 0;padding: 8px 0;"> <div class="col-xs-1" style="text-align: right"> {% category_all arg_dict %} </div> <div class="col-xs-11"> {% category_combine category_list arg_dict %} </div> </div> <div class="conditions row clearfix" style="margin: 0;padding: 8px 0;"> <div class="col-xs-1" style="text-align: right"> {% article_type_all arg_dict %} </div> <div class="col-xs-11"> {% article_type_combine type_list arg_dict %} </div> </div> </div> <div class="clearfix" style="height: 36px;line-height: 35px;padding: 0 15px;border-top: 1px solid #dddddd;background-color: #f1f0f0"> <i class="fa fa-table" aria-hidden="true"></i> 搜索文章({{ data_count }}篇) <a target="_blank" href="/backend/add-article.html" class="right" style="display: inline-block;padding:0 10px;background-color: #428bca;color: #ffffff;"> <i class="fa fa-plus-circle" aria-hidden="true"></i> 创建新文章 </a> </div> <table class="table table-bordered"> <thead> <tr> <th>文章标题</th> <th>操作</th> </tr> </thead> <tbody> {% for row in result %} <tr nid="{{ row.nid }}"> <td><a href="/{{ row.blog.site }}/{{ row.nid }}.html">{{ row.title }}</a></td> <td> <a class="btn btn-danger btn-xs" onClick="return confirm('确定删除?');" href="/backend/del-article-{{ row.nid }}.html"> <i class="fa fa-times" aria-hidden="true"></i> 删除 </a> | <a class="btn btn-primary btn-xs" href="/backend/edit-article-{{ row.nid }}.html"> <i class="fa fa-pencil-square-o" aria-hidden="true"></i> 编辑 </a> </td> </tr> {% endfor %} </tbody> </table> <div class="clearfix"> <ul class="pagination right" style="margin-top: 0"> {{ page_str }} </ul> </div> </div> {% endblock %} {% block js %} <script> function search(){ //1:拿到url var url =window.location.href; //2: 判断是否有? url=url.substring(0,url.indexOf("?")) url =url+"?keyWord="+$("#keyWord").val(); javascript:window.location.href=url; } </script> {% endblock %}
from django.shortcuts import render,redirect,HttpResponse from repository import models from web.Views.Tools import AaronPager from web.Views.Tools.pagination import Pagination from django.urls import reverse from forms.article import ArticleForm #引用form中的文章表单,用于添加、修改文章 from django.db import transaction #引用事务 from utils.xss import XSSFilter #引用Xss安全机制,存储富文本编辑器中内容 from utils.pagination import Pagination import datetime #引入时间模块 def index(request): return render(request, 'Backend/backend_index.html') def article(request, *args, **kwargs): """ 博主个人文章管理 :param request: :return: """ # 通过session拿掉用户的登录信息 blog_id = request.session['user_info']['bloginfo__bid'] condition = {} # 遍历kwargs条件(ms_Type、classification_id) for k, v in kwargs.items(): if v == '0': pass else: condition[k] = v condition['blog_id'] = blog_id condition['status'] =1 # 筛选出文章总数 data_count = models.Article.objects.filter(**condition).count() if request.GET.get("keyWord"): data_count = models.Article.objects.filter(**condition,title__contains=request.GET.get("keyWord")).count() # 获取页数 page = Pagination(request.GET.get('p', 1), data_count) # 筛选出文章列表 result = models.Article.objects.filter(**condition).order_by('-nid').only('nid', 'title','blog').select_related('blog')[page.start:page.end] if request.GET.get("keyWord"): result = models.Article.objects.filter(**condition, title__contains=request.GET.get("keyWord")).order_by('-nid').only('nid', 'title', 'blog').select_related('blog')[ page.start:page.end] #通过通用方法,生成分页 page_str = page.page_str(reverse('article', kwargs=kwargs)) #获取分类内容 category_list = models.Classification.objects.filter(blog_id=blog_id).values('nid', 'title') # 获取类型内容 type_list = map(lambda item: {'nid': item[0], 'title': item[1]}, models.Article.masterStation_type) kwargs['p'] = page.current_page return render(request, 'Backend/backend_article.html', {'result': result, 'page_str': page_str, 'category_list': category_list, 'type_list': type_list, 'arg_dict': kwargs, 'data_count': data_count, 'keyWord':request.GET.get("keyWord") if request.GET.get("keyWord") else '' } ) def add_article(request): # 添加文章 if request.method == "GET": form = ArticleForm(request=request) return render(request,"Backend/add_article.html",{'form':form ,'oper':'add','nid':-1}) elif request.method=='POST': oper=request.GET.get('oper', 'add') nid =int(request.GET.get('nid', -1)) if oper =='add': form = ArticleForm(request=request,data=request.POST) if form.is_valid(): with transaction.atomic(): tags=form.cleaned_data.pop('tags') content = form.cleaned_data.pop('content') content=XSSFilter().process(content) form.cleaned_data['blog_id']=request.session['user_info']["bloginfo__bid"] # 需要将该值转化一下 form.cleaned_data['classification_id']=models.Classification.objects.filter(nid=form.cleaned_data['classification_id']).first() form.cleaned_data['create_time'] = datetime.datetime.now() obj = models.Article.objects.create(**form.cleaned_data) #添加文章 models.Article_Detail.objects.create(detail=content,article_id=obj) #添加文章详细 tag_list=[] for tag_id in tags: tag_id=int(tag_id) tag_list.append(models.Article_Tag(article_id_id=obj.nid,tag_id_id=tag_id)) models.Article_Tag.objects.bulk_create(tag_list) #批量创建,厉害 return redirect("backend/article-0-0.html") else: return render(request, "backend/add_article.html",{'form':form,'oper':'add','nid':-1}) elif oper=="edit" and nid>0: blog_id = request.session['user_info']['bloginfo__bid'] form = ArticleForm(request=request, data=request.POST) if form.is_valid(): obj = models.Article.objects.filter(nid=nid, blog_id=blog_id, status=1).first() if not obj: return HttpResponse('该文章不存在或已删除') with transaction.atomic(): tags = form.cleaned_data.pop('tags') content = form.cleaned_data.pop('content') content = XSSFilter().process(content) form.cleaned_data['blog_id'] = request.session['user_info']["bloginfo__bid"] # 需要将该值转化一下 form.cleaned_data['classification_id'] = models.Classification.objects.filter( nid=form.cleaned_data['classification_id']).first() form.cleaned_data['create_time'] = datetime.datetime.now() obj = models.Article.objects.filter(nid=obj.nid, status=1).update(**form.cleaned_data) # 修改文章 models.Article_Detail.objects.filter(article_id_id=nid, status=1).update(detail=content ) # 修改文章详细 models.Article_Tag.objects.filter(article_id_id=nid).delete() #使用之前,先把该文章下面的所有标签删除 tag_list = [] for tag_id in tags: tag_id = int(tag_id) tag_list.append(models.Article_Tag(article_id_id=nid, tag_id_id=tag_id)) models.Article_Tag.objects.bulk_create(tag_list) # 批量创建,不知道更新的时候是否有问题 return redirect("backend/article-0-0.html") else: return render(request, "backend/add_article.html", {'form': form,'oper':'edit','nid':nid}) else: return redirect('/') else: return redirect('/') def del_article(request, nid): # 删除文章 blog_id = request.session['user_info']['bloginfo__bid'] nid=int(nid) v=models.Article.objects.filter(blog_id=blog_id,nid=nid).update(status=0) if not v: return HttpResponse('删除失败') return redirect("backend/article-0-0.html") def edit_article(request, nid): # 编辑文章 blog_id = request.session['user_info']['bloginfo__bid'] if request.method == "GET": # 查找数据库中该条数据 obj=models.Article.objects.filter(nid=nid,blog_id=blog_id,status=1).first() if not obj: return HttpResponse('该文章不存在或已删除') # 获取该文章的标签 tags=obj.tags.values_list('nid') if tags: tags = list(zip(*tags))[0] init_dict={ 'nid':obj.nid, 'title':obj.title, 'summary':obj.summary, 'content':obj.article_detail.detail if hasattr(obj, 'article_detail') else '', 'ms_Type':obj.ms_Type, 'classification_id':obj.classification_id_id, 'tags': tags } form = ArticleForm(request=request, data=init_dict) # 页面内容一致,可以简化使用新增的页面 return render(request, 'Backend/add_article.html', {'form': form,'oper':'edit','nid':nid}) else: return redirect('/')