• 饮冰三年-人工智能-Python-32博客园山寨版之后台管理


    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'),
    
    ]
    urls.py

     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>
    backend_layout.html

     1.3 设置首页    

    {% extends 'Backend/backend_layout.html' %}
    {% block css %}
    
    {% endblock %}
    {% block conent %}
       <h1>欢迎登陆:{{ request.session.user_info.username }}</h1>
    {% endblock %}
    
    {% block js %}
    
    {% endblock %}
    backend_index.html

      由路由可知,调用后台的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')
    user.pyp

     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 %}
    backend_article.html
    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
                       }
                      )
    user.py

     其中涉及到一个分页的帮助类

    __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
    pagination.py

     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')
    Form==》article.py

     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 %}
    backend_article.html

     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('/')
    user.py

      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>
    部分backend_article.html

      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),#删除文章路由
    ]
    urls.py

      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")
    user.py

     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 %}
    backend_article.html

      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),#修改文章路由
    ]
    urls.py

      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('/')
    user.py

         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 %}
    add_article.html

     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('/')
    后台逻辑
  • 相关阅读:
    程序员修炼之道:从小工到专家有感2
    3月13日
    第一次结对作业(2)
    3月12日
    3月11日
    第一次结对作业
    3月10日
    11月6日
    10月28日
    10月7日
  • 原文地址:https://www.cnblogs.com/YK2012/p/10921513.html
Copyright © 2020-2023  润新知