• python全栈开发day78、79 --bss项目


    一、回顾 

        1. BBS项目 CMS
            1. 登录
                1. form组件
                2. auth模块
                3. 验证码
            2. 注册
                1. form组件
                    1. 生成html代码
                        直接for循环form_obj,就能够遍历所有字段
                    2. 验证
                        1. 默认的那些验证
                        2. 正则的验证
                        3. 全局钩子做确认密码的验证
                        4. 判断用户名是否已经存在
                            1. input框失去焦点就发ajax到后端判断
                            2. form组件中使用局部钩子来判断    
                        
                2. auth模块 --> 扩展auth_user表 --> create_user()
                    1. UserInfo这个类里面,avatar是一个FileField
                        avatar = models.FileField(upload_to="avatars/", default="avatars/default.png")
                    2. 注意事项:
                        1. FileField保存的是一个路径,而不是一个文件
                        2. upload_to:具体保存的文件路径就会在media目录下
                3. 上传头像
                    1. ajax如何上传文件
                    2. Django中media的配置
                        1. settings.py中:
                            - MEDIA_URL:别名
                            - MEDIA_ROOT:给用户上传的所有文件指定一个存放目录
                        2. urls.py中:
                            from django.views.static import serve
                            from django.conf import settings
                            
                            url(r'^media/(?P<path>.*)', serve, {"document_root": settings.MEDIA_ROOT})
            3. 博客首页
                1. 文章列表(排样式)
                2. 分页
                    1. 封装的要彻底
                    2. 封装后的结果要有普适性(url要写成配置项)
            4. 个人博客主页
                1. 分类
                    1. 文章分类
                    2. 文章标签
                2. 日期归档
                    1. 日期格式化函数    --> MySQL内置的函数都有哪一些?      --> 《漫画数据库》
                        1. MySQL:DATE_FORMAT('字段', '格式')
                        2. sqlite:strftime('格式', '字段')
                    
                    2. ORM中如何执行原生的SQL语句
                        1. 使用extra()在执行ORM查询的同时,嵌入一些SQL语句
                        2. 直接执行原生SQL语句
                            from django.db import connection
                            cursor = connection.cursor()
                            cursor.execute('select id from userinfo;')
                            cursor.fetchall()    
                    3. 分组聚合
                        QuertySet.annotate()  --> 分组,前面查的是什么字段就按什么字段分组        
                        QuertySet.aggregate() --> 聚合,给QuerySet中的每个对象多一个属性
                        
                    4. 4合1路由
                        不同的路由可以使用同一个视图函数!!! --> 视图函数中通过参数的不同,实现不同的功能
            5. 文章详情页
                1. 母板继承
                2. inclusion_tag
                    1. 返回一段HTML代码,用数据填充的HTML代码
                    2. 具体的写法
                        1. 在app下面创建一个名为 templatetags 的 Python Package
                        2. 在上面的包中创建一个 py文件
                        3. 按照inclusion_tag的格式要求写功能函数
                            
                            from django import template
                            register = template.Library()
                            
                            @register.inclusion_tag(file='xx.html')
                            def show_menu(*arg):
                                ...
                                return {"k1": "v1"}
                                (xx.html中使用k1这个变量)    
                3. 点赞
                    1. ajax发送点赞的请求
                        1. 点赞必须是登录用户,没登录跳转到登录页面
                        2. 不能给自己的文章点赞
                        3. 一个用户只能给一篇文章点一次赞或踩一次
                    
                    2. 后端创建点赞记录(事务操作)
                        1. 创建新的点赞记录
                        2. 去对应的文章表里把点赞数更新一个
                    3. ORM事务操作
                        from django.db import transaction
                        
                        with transaction.atomic():
                            sql1;
                            sql2;
                            
                    4. Django模板语言里面的JS代码
                        如何在js中引用模板语言的变量,注意加引号!!!
    bss项目回顾

    二、今日内容(评论楼和评论树)

     1.评论展示HTML:注意给每个评论楼层添加一个comment_id,后续别人回复改评论,取其值为父评论id

        <!-- 评论展示部分 开始-->
        <div class="list-group commnet_list">
            {% for comment in comment_list %}
    
                <a href="javascript:void(0);" class="list-group-item">
                    <h4 class="list-group-item-heading" pid='{{ comment.id }}'>
                        <span>{{ forloop.counter }}楼</span>
                        <span>{{ comment.create_time|date:'Y-m-d H:i:s' }}</span>
                        <span>{{ comment.user.username }}</span>
                        <span class="pull-right reply">回复</span>
                    </h4>
                    {% if  comment.parent_comment %}
                        <span style="display: block;color: blue">@{{ comment.parent_comment.user.username }}</span>
                    {% endif %}
                    <p class="list-group-item-text" style="text-indent:20px; ">{{ comment.content }}</p>
                </a>
            {% endfor %}
        </div>
        <!-- 评论展示部分 结束-->
    评论展示HTML

    2.设置事件委托,点击回复定位至评论框,并在评论框内设置出现@用户名,存储comment_id 至button标签

            $('.list-group').on('click', '.reply', function () {
                var replyName = $(this).prev().text();
                $('#new-comment').focus().val('@' + replyName + '
    ');
                var pId = $(this).parent().attr('pid');
                $('#submit').data('pId', pId);
            })
    存父评论pid等

    3.评论区书写代码

        <!-- 评论书写部分 开始-->
        <hr>
        <h4>发表评论</h4>
        <hr>
        <div>
            <span>用户名:</span>
            <input type="text" value="{{ request.user.username }}" disabled>
        </div>
        <div>
            <p>评论:</p>
            <textarea name="comment" id="new-comment" cols="60" rows="10"></textarea>
        </div>
        <div>
            <button class="btn" id="submit">提交</button>
        </div>
        <div style=" 100%;height: 100px;"></div>
    
        <!-- 评论书写部分 结束-->
    评论区HTML代码

    4.ajax提交内容,通过button标签中存储的pid是否存在判断是子评论还是一级评论并处理评论内容(去除@XXX),ajax提交并返回响应数据,js添加响应html代码至浏览器。

    $('#submit').click(function () {
                var content = $('#new-comment').val();
                var articleId = '{{ article.id }}';
                var parentId = $('#submit').data('pId') || "";
                if (parentId) {
                    content = content.slice(content.indexOf('
    ') + 1,)
                }
                $.ajax({
                    url: '/comment/?next=' + '{{ request.get_full_path }}',
                    type: 'post',
                    data: {
                        content: content,
                        article_id: articleId,
                        parent_id: parentId,
                        csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
                    },
                    success: function (res) {
                        if (res.code === 0) {
                            var count = $('.commnet_list>a').length+1;
                            {#判断是否需要@回复,还是一级评论#}
                            if (res.data.parentName) {
                                var reply_html = `<span style="display: block;color: blue">@${res.data.parentName }</span>`;
                            } else {
                                var reply_html = ''
                            }
                            var comment_html = `
                                 <a href="javascript:void(0);" class="list-group-item">
                                    <h4 class="list-group-item-heading" pid='${ res.data.commentId }'>
                                        <span>${ count }楼</span>
                                        <span>${ res.data.create_time}</span>
                                        <span>${ res.data.username }</span>
                                        <span class="pull-right reply">回复</span>
                                    </h4>`+reply_html+
                                    `<p class="list-group-item-text" style="text-indent:20px; ">${ res.data.content }</p> </a>`
                            $('.commnet_list').append(comment_html);
                            $('#new-comment').val('');
                            $('#submit').removeData('pId')
                        }
                    }
                })
    
            })
    
        </script>
    
    
        <script>
            var userId = '{{ request.user.pk }}';
            var articleId = '{{ article.id }}';
            var isUp = false;
            $(".digg").click(function () {
                var username = '{{ username }}'
                var loginname = '{{ request.user.username }}'
                if (!'{{ request.user.username }}') {
                    {#如果用户未登录,跳转到登录页面#}
                    location.href = '/login2/?next=' + '{{ request.get_full_path }}';
                }
                    {#如果用户给自己点赞或反对,不行#}
                else if (username == loginname) {
                    if ($(this).hasClass('diggit')) {
                        $('#msg').text('不能给自己点赞!').css('color', 'red');
                    } else {
                        $('#msg').text('不能反对自己!').css('color', 'red');
                    }
                }
                else {
                    if ($(this).hasClass('diggit')) {
                        isUp = true;
                    }
                    $.ajax({
                        url: '/evalute/',
                        type: 'post',
                        data: {
                            csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
                            userId: userId,
                            articleId: articleId,
                            isUp: isUp,
                        },
                        success: function (res) {
                            if (res.code !== 0) {
                                $('#msg').text(res.msg).css('color', 'red');
                            } else {
    
                                if (isUp) {
                                    var $up = $('#digg_count')
                                    $up.text(+$up.text() + 1)
                                } else {
                                    var $down = $('#bury_count')
                                    $down.text(+$down.text() + 1)
    
                                }
                            }
    
                        }
                    })
                }
            })
            {#用户对已点赞或踩灭的文章进行取消!显示#}
            $('document').ready(function () {
                $.ajax({
                    url: '/cancel/',
                    type: 'post',
                    data: {
                        userId: '{{ request.user.id }}',
                        articleId: '{{ article.id }}',
                        csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
                    },
                    success: function (res) {
                        if (res.code === 0) {
                            if (res.msg === 1) {
                                $('#digg_tips').html('您已推荐过,<a href="javascript:void(0);" class="digg_gray">取消 </a>');
                            }
                            else {
                                $('#digg_tips').html('您已反对过,<a href="javascript:void(0);" class="digg_gray">取消 </a>');
                            }
                        } else {
                            $('#digg_tips').css('display', 'none');
                        }
                    }
                })
            })
    
            $('#digg_tips').click(function () {
                $.ajax({
                    url: '/cancel1/',
                    type: 'post',
                    data: {
                        userId: '{{ request.user.id }}',
                        articleId: '{{ article.id }}',
                        csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val()
                    },
                    success: function (res) {
                        if (res.code !== 0) {
                            $('#digg_tips').html('推荐取消失败,<a href="javascript:void(0);" class="digg_gray">刷新重试</a>');
                        } else {
                            location.reload();
                        }
                    }
                })
            })
    View Code

    三、预习和扩展

    1.模板中表单的简单写法

    2.注册过程中检验是否存在同名用户的局部钩子

    3.DOM元素存储data、获取data、删除data

    4.JS三元运算和 ||

    5.JS字符串截取

    6.事件委托的运用

    7. js字符串前加+号可以将字符串变成数字:

    $down.text(+$down.text() + 1)

     

  • 相关阅读:
    UVALive 7146 (贪心+少许数据结构基础)2014acm/icpc区域赛上海站
    hdu 1754 I Hate It(树状数组区间求最值)2007省赛集训队练习赛(6)_linle专场
    【进阶——树状数组】 区间求最值
    软件测试作业4
    软件测试作业三 尝试使用JUnit
    软件测试作业2:读代码回答问题
    软件测试作业1:描述一个曾遇到的错误
    hdu1064Financial Management
    hdu1161Eddy's mistakes
    hdu1020Encoding
  • 原文地址:https://www.cnblogs.com/wuchenggong/p/9505569.html
Copyright © 2020-2023  润新知