day70-BBS

HTML

{% extends 'base.html' %}


{% block css %}
    <style>
        #div_digg {
            float: right;
            margin-bottom: 10px;
            margin-right: 30px;
            font-size: 12px;
            width: 128px;
            text-align: center;
            margin-top: 10px;
        }

        .diggit {
            float: left;
            width: 46px;
            height: 52px;
            background: url('/static/image/upup.gif') no-repeat;
            text-align: center;
            cursor: pointer;
            margin-top: 2px;
            padding-top: 5px;
        }

        .buryit {
            float: right;
            margin-left: 20px;
            width: 46px;
            height: 52px;
            background: url('/static/image/downdown.gif') no-repeat;
            text-align: center;
            cursor: pointer;
            margin-top: 2px;
            padding-top: 5px;
        }

        .clear {
            clear: both;
        }

        .diggword {
            margin-top: 5px;
            margin-left: 0;
            font-size: 12px;
            color: gray;
        }
    </style>
{% endblock %}

{% block content %}
    <h1>{{ article_obj.title }}</h1>
    {{ article_obj.content|safe }}
    {#    点赞点踩前端样式#}
    <div class="clearfix">
    <div>
        <div id="div_digg">
            <div class="diggit action" >
                <span class="diggnum" id="digg_count">{{ article_obj.up_num }}</span>
            </div>
            <div class="buryit action">
                <span class="burynum" id="bury_count">{{ article_obj.down_num }}</span>
            </div>
            <div class="clear"></div>
            <div class="diggword" id="digg_tips">
                <span style="color: red" id="id_info"></span>
            </div>
        </div>
    </div>
    </div>
    {#    点赞点踩结束#}
{#    评论楼渲染开始#}
{#    #51楼 2018-12-05 15:50 漏网的小鱼  #}
    <h4>评论列表:</h4>
    <ul class="list-group">
 {% for comment in page_queryset %}
     <li class="list-group-item">
         <div>
             <span>#{{ forloop.counter }}楼</span>
             <span>{{ comment.create_time|date:'Y-m-d' }}</span>
             <span><a href="/{{ comment.user.username }}/">{{ comment.user.username }}</a></span>
             <span class="pull-right reply" username="{{ comment.user.username }}" comment_id="{{ comment.pk }}"><a>回复</a></span>
         </div>
         {% if comment.parent %}
            <p><a href="#">@</a>{{ comment.parent.user.username }}</p>
         {% endif %}
         {{ comment.content }}
     </li>n
    {% endfor %}
    {{ page_obj.page_html|safe }}
</ul>

{#    评论楼渲染结束#}

    {#    评论样式开始#}
    <div>
    <p><span class="glyphicon glyphicon-comment"></span>发表评论</p>
    <p>
    昵称:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}">
    </p>
    <p>评论内容:</p>
    <p>
        <textarea name="" id="id_comment" cols="60" rows="10" ></textarea>
    </p>
    <p>
        <input type="button" class="btn btn-primary" value="提交评论" id="id_submit">
    </p>
    </div>

    {#    评论样式结束#}
    <script>
        // 点赞点踩逻辑代码
        $('.action').click(function () {
            var isUp = $(this).hasClass('diggit');
            var $spanEle = $(this).children();
            $.ajax({
                url:'/up_or_down/',
                type:'post',
                data:{'is_up':isUp,'article_id':{{ article_obj.pk }},'csrfmiddlewaretoken':'{{ csrf_token }}'},
                success:function (data) {
                    if (data.code == 2000){
                        $('#id_info').html(data.msg);
                        $spanEle.text(Number($spanEle.text()) + 1);
                    }else{
                        $('#id_info').html(data.msg)
                    }
                }
            })
        });


       
       
        var parentId = null;                                                 // 定义一个全局的parantId变量名
        $("#id_submit").click(function () {
            var comment = $('#id_comment').val();
            if (parentId){
                
                
                var nIndex = comment.indexOf('\n') + 1;                      // 先获取\n所在的索引值
                comment = comment.slice(nIndex);                             // 将comment中的@人名清空掉
            }
            $.ajax({
                url:'/comment/',
                type:'post',
                data:{
                    'comment':comment,
                    'article_id':{{ article_obj.pk }},
                    'csrfmiddlewaretoken':'{{ csrf_token }}',
                    'parent_id':parentId
                },
                success:function (data) {
                    if(data.code == 2000){
                       
                        
                        var userName = '{{ request.user.username }}';        // 获取用户名
                        
                        var comment = $('#id_comment').val();                // 获取评论内容
                       
                        var tempStr = `                                         // 动态生成li标签
                        <li class="list-group-item">
                         <div>
                             <span class='glyphicon glyphicon-comment'></span><span>${userName}:</span>
                         </div>
                            ${comment}
                         </li>
                        `;
                      
                        $('.list-group').append(tempStr);                      // 查找url标签 将上面的字符串追加到ul标签内
                        
                        $('#id_comment').val('');
                        parentId = null;
                    }
                }
            })

        });

        // 点击回复按钮发生了下面三件事
        $('.reply').click(function () {
            
            var userName = $(this).attr('username');             // 获取当前回复按钮所对应的根评论的用户名
            $('#id_comment').html('@'+userName+'\n').focus();    // .focus()自动获取焦点              
            parentId = $(this).attr('comment_id');                // 将全局的parentId修改
        })
    </script>
{% endblock %}
{% extends 'backend/backendbase.html' %}


{% block content %}
    <h3>添加文章</h3>
    <hr>
    <form action="" method="post">
        {% csrf_token %}
        <p>标题</p>
        <input type="text" name="title" id="id_title" class="form-control">
        <p>内容(kindeditor编辑器,支持拖放/粘贴上传图片)</p>
        <p>
            <textarea name="content" id="id_content" cols="30" rows="10"></textarea>
        </p>
        <input type="submit" value="发布" class="btn btn-danger">
    </form>



    <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:'450px',
                resizeType:0,
                
                uploadJson : '/upload_img/',            // 控制文件上传的位置
                 extraFileUploadParams : {
                        'csrfmiddlewaretoken':'{{ csrf_token }}'

                }
            });
        });
    </script>
{% endblock %}

views

from django.contrib.auth.decorators import login_required
from django.db import transaction                       # django中开启事务 需要先倒入该模块


@login_required
def comment(request):
    back_dic = {'code':None,'msg':''}
    if request.is_ajax():
        comment = request.POST.get('comment')
        article_id = request.POST.get('article_id')
        parent_id = request.POST.get('parent_id')
        with transaction.atomic():                                                                                           # 在with代码块写的就是一个事务
            
            
            models.Article.objects.filter(pk=article_id).update(comment_num = F('comment_num') + 1)                           # 文章表修改comment_num字段
          
            models.Comment.objects.create(user=request.user,article_id=article_id,content=comment,parent_id=parent_id)        # 评论表里面新增数据
        back_dic['code'] = 2000
        back_dic['msg'] = '评论成功'
    return JsonResponse(back_dic)


# 后台管理
@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())


from bs4 import BeautifulSoup
def add_article(request):
    if request.method == 'POST':
        title = request.POST.get('title')
        content = request.POST.get('content')
        
        res = BeautifulSoup(content,'html.parser')                  # 能够帮我拿到当前用户写的所有的标签
        tags = res.find_all()
        for tag in tags:
            
            if tag.name == 'script':
                tag.decompose()                                     # 删除指定的标签
       
        desc = res.text[0:150]                                        # 用户输入的文本值切片

        models.Article.objects.create(title=title,content=str(res),desc=desc,blog=request.user.blog)
        return redirect('/backend/')
    return render(request,'backend/add_article.html')

from BBS import settings
import os
def upload_img(request):
    back_dic = {'error':''}
    if request.method == 'POST':
       
        img_obj = request.FILES.get('imgFile')
       
        path = os.path.join(settings.BASE_DIR,'media','upload_img')      # 规定编辑器上传的图片全部放到media文件夹里面的upload_img文件夹下
        if not os.path.exists(path):
            os.mkdir(path)
        file_path = os.path.join(path,img_obj.name)
        with open(file_path,'wb') as f:
            for line in img_obj:
                f.write(line)
       
        back_dic['error'] = 0
        back_dic['url'] = '/media/upload_img/%s'%img_obj.name            # 2.将文件路径返回给前端
        """
        //成功时
        {
                "error" : 0,
                "url" : "http://www.example.com/path/to/file.ext"
        }
        //失败时
        {
                "error" : 1,
                "message" : "错误信息"
        }
        
        """
    return JsonResponse(back_dic)


@login_required
def set_avatar(request):
    username = request.user.username
    if request.method == 'POST':
        new_avatar = request.FILES.get('new_avatar')
       
        # models.Userinfo.objects.filter(pk=request.user.pk).update(avatar=new_avatar)           # 如果用queryset对象更新头像 不会自动帮你拼接前缀
        user_obj = models.Userinfo.objects.filter(pk=request.user.pk).first()
        user_obj.avatar = new_avatar
        user_obj.save()
        return redirect('/home/')
    return render(request,'set_avatar.html',locals())

 

上一篇:Django项目 BBS论坛


下一篇:BBS之文章详情页搭建