zoukankan      html  css  js  c++  java
  • Django框架15

    内容回顾

    • 登陆功能后端实现

      # 前后端基于ajax交互的话 那么后端通常会返回字典格式数据
      """
      1.验证码判断是否正确
          忽略大小写
      """
    • 首页搭建

      # django admin后台管理
      """
      urls.py自带的那个url
      ​
      特点:
          能够自动生成注册了的模型表的增删改查四条url及相应的界面
      ​
      使用
          在对应的应用下的admin.py文件中注册模型表即可
          admin.site.register(models.UserInfo)
          ...
      class UserInfo(models.Model):
          username = models.CharField(verbose_name='字段名')
          class Meta:
              verbose_name_plural = '表名'
      ​
      针对bbs在绑定数据的时候一定要细心
          1.先去文章表里面绑定数据
          2.个人站点
          3.文章分类
          4.将用户和个人站点绑定关系
          5.文章与文章标签
      ​
      扩展:admin路由分发的本质
              # 路由分发本质    include  可以无限制的嵌套N多层
              url(r'^index/',([],None,None))
              
          # url(r'^index/',([
          #         url(r'^index_1/',([
          #                 url(r'^index_1_1',index),
          #                 url(r'^index_1_2',index),
          #                 url(r'^index_1_3',index),
          #                           ],None,None)),
          #         url(r'^index_2/',index),
          #         url(r'^index_3/',index),
          #                 ],None,None)),
      """
    • media配置

      """
      网址所使用到的静态资源默认都是放在static文件夹下
      用户上传的静态文件资源也应该单独找个位置存放
      ​
      media配置
          settings.py
              MEDIA_ROOT = os.path.join(BASE_DIR,'media')
      用户上传文件会自动创建media文件夹然后在该文件夹内存储数据
      """
    • 如何自定义暴露后端资源

      # 你需要自己在urls.py中书写代码
      from django.views.static import serve
      from BBS14 import settings
      ​
      # 固定写法 不要自己改动
      url(r'^media/(?P<path>.*)',serve,{'document_root':settings.MEDIA_ROOT}),
    • 个人站点

      # 由于url方法第一个参数是正则表达式,所有当路由特别多的时候,可能会出现被顶替的情况,针对这种情况有两种解决方式
          1.修改正则表达式
        2.调整url方法的位置
      ​
      """
      1.页面布局不再是282 变成左右布局
      2.个人站点每个人的样式都不一样内部大致如何实现的
          内部给每个人开设了可以自定义css和js的文件接口并且用户自定义之后会将用户的文件保存下来,之后在打开用户界面的时候会自动加载用户自己写的css和js从而实现每个用户界面不一样的情况
      3.侧边栏展示问题
          只要你的orm学的没有问题一般情况下不会有难度
          只要是queryset对象就可以无限制的点击queryset对象方法
              filter().filter().filter().filter()
          
          # 1 查询当前用户所有的分类及分类下的文章数
          # 2 查询当前用户所有的标签及标签下的文章数
          # 3 按照年月统计所有的文章
              1.需要截取日期字段
                  参考官网提供的方法
                      from django.db.models.functions import TruncMonth
                      date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values('month').annotate(count_num=Count('pk')).values_list('month','count_num')
          
              2.如果按照上述写法出现报错,那么需要你去配置文件中修改时区
              TIME_ZONE = 'Asia/Shanghai'
              USE_TZ = False
      4.侧边栏筛选功能
          1.多个url公用一个视图函数
          2.当多个url公用一个视图函数的时候 你应该思考着多个url能不能优化一下
              # 个人站点页面搭建
          url(r'^(?P<username>w+)/$',views.site,name='site'),
          # 侧边栏筛选功能
          # url(r'^(?P<username>w+)/category/(d+)/',views.site),
          # url(r'^(?P<username>w+)/tag/(d+)/',views.site),
          # url(r'^(?P<username>w+)/archive/(w+)/',views.site),
          # 上面的三条url其实可以合并成一条
          url(r'^(?P<username>w+)/(?P<condition>category|tag|archive)/(?P<param>.*)/',views.site)
          
          
              if kwargs:
              # print(kwargs)  # {'condition': 'tag', 'param': '1'}
              condition = kwargs.get('condition')
              param = kwargs.get('param')
              # 判断用户到底想按照哪个条件筛选数据
              if condition == 'category':
                  article_list = article_list.filter(category_id=param)
              elif condition == 'tag':
                  article_list = article_list.filter(tags__id=param)
              else:
                  year,month = param.split('-')  # 2020-11  [2020,11]
                  article_list = article_list.filter(create_time__year=year,create_time__month=month)
      ​
      5.手动补全侧边栏url即可
      """

    今日内容概要

    ps:今日内容比较繁琐(逻辑和代码量稍微多了一点),认真听~

    • 侧边栏制作成inclusion_tag

    • 文章的点赞点踩(重点)

    • 文章的评论(重点)

      • 先只做根评论

      • 之后再做子评论

      • 小bug完善

    文章详情页

    # url设计
    /username/article/1# 先验证url是否会被其他url顶替
    # 文章详情页和个人站点基本一致 所以用模版继承
    # 侧边栏的渲染需要传输数据才能渲染 并且该侧边栏在很多页面都需要使用
        1.哪个地方用就拷贝需要的代码(不推荐 有点繁琐)
      
      2.将侧边栏制作成inclusion_tag    
      """
      步骤
        1.在应用下创建一个名字必须叫templatetags文件夹
        2.在该文件夹内创建一个任意名称的py文件
        3.在该py文件内先固定写两行代码
            from django import template
            register = template.Library()
            # 自定义过滤器
            # 自定义标签
            # 自定义inclusion_tag
      
      """
      # 自定义inclusion_tag
    @register.inclusion_tag('left_menu.html')
    def left_menu(username):
        # 构造侧边栏需要的数据
        user_obj = models.UserInfo.objects.filter(username=username).first()
        blog = user_obj.blog
        # 1 查询当前用户所有的分类及分类下的文章数
        category_list = models.Category.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list(
            'name', 'count_num', 'pk')
        # print(category_list)  # <QuerySet [('jason的分类一', 2), ('jason的分类二', 1), ('jason的分类三', 1)]>
    # 2 查询当前用户所有的标签及标签下的文章数
        tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list('name',
                                                                                                             'count_num',
                                                                                                             'pk')
        # print(tag_list)  # <QuerySet [('tank的标签一', 1), ('tank的标签二', 1), ('tank的标签三', 2)]>
    # 3 按照年月统计所有的文章
        date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values(
            'month').annotate(count_num=Count('pk')).values_list('month', 'count_num')
        # print(date_list)
        return locals()

    文章点赞点踩

    """
    浏览器上你看到的花里胡哨的页面,内部都是HTML(前端)代码
    ​
    那现在我们的文章内容应该写什么???  >>> html代码
    ​
    如何拷贝文章
        copy outerhtml
    ​
    1.拷贝文章
    2.拷贝点赞点踩
        1.拷贝前端点赞点踩图标 只拷了html
        2.css也要拷贝
            由于有图片防盗链的问题 所以将图片直接下载到本地
    ​
    思考:
        前端如何区分用户是点了赞还是点了踩
        1.给标签各自绑定一个事件
            两个标签对应的代码其实基本一样,仅仅是是否点赞点踩这一个参数不一样而已
        2.二合一
            给两个标签绑定一个事件
            //   给所有的action类绑定事件
        $('.action').click(function () {
                alert($(this).hasClass('diggit'))
            })
    ​
    由于点赞点踩内部有一定的业务逻辑,所以后端单独开设视图函数处理
    ​
    """
    # 个人建议:写代码先把所有正确的逻辑写完再去考虑错误的逻辑 不要试图两者兼得
    import json
    from django.db.models import F
    def up_or_down(request):
        """
        1.校验用户是否登陆
        2.判断当前文章是否是当前用户自己写的(自己不能点自己的文章)
        3.当前用户是否已经给当前文章点过了
        4.操作数据库了
        :param request:
        :return:
        """
        if request.is_ajax():
            back_dic = {'code':1000,'msg':''}
            # 1 先判断当前用户是否登陆
            if request.user.is_authenticated():
                article_id = request.POST.get('article_id')
                is_up = request.POST.get('is_up')
                # print(is_up,type(is_up))  # true <class 'str'>
                is_up = json.loads(is_up)  # 记得转换
                # print(is_up, type(is_up))  # True <class 'bool'>
                # 2 判断当前文章是否是当前用户自己写的  根据文章id查询文章对象 根据文章对象查作者 根request.user比对
                article_obj = models.Article.objects.filter(pk=article_id).first()
                if not article_obj.blog.userinfo == request.user:
                    # 3 校验当前用户是否已经点了      哪个地方记录了用户到底点没点
                    is_click = models.UpAndDown.objects.filter(user=request.user,article=article_obj)
                    if not is_click:
                        # 4 操作数据库 记录数据      要同步操作普通字段
                        # 判断当前用户点了赞还是踩 从而决定给哪个字段加一
                        if is_up:
                            # 给点赞数加一
                            models.Article.objects.filter(pk=article_id).update(up_num = F('up_num') + 1)
                            back_dic['msg'] = '点赞成功'
                        else:
                            # 给点踩数加一
                            models.Article.objects.filter(pk=article_id).update(down_num=F('down_num') + 1)
                            back_dic['msg'] = '点踩成功'
                        # 操作点赞点踩表
                        models.UpAndDown.objects.create(user=request.user,article=article_obj,is_up=is_up)
                    else:
                        back_dic['code'] = 1001
                        back_dic['msg'] = '你已经点过了,不能再点了'  # 这里你可以做的更加的详细 提示用户到底点了赞还是点了踩
                else:
                    back_dic['code'] = 1002
                    back_dic['msg'] = '你个臭不要脸的!'
            else:
                back_dic['code'] = 1003
                back_dic['msg'] = '请先<a href="/login/">登陆</a>'
            return JsonResponse(back_dic)
    ​
    <script>
            //   给所有的action类绑定事件
            $('.action').click(function () {
                {#alert($(this).hasClass('diggit'))#}
                let isUp = $(this).hasClass('diggit');
                let $div = $(this);
                // 朝后端发送ajax请求
                $.ajax({
                    url:'/up_or_down/',
                    type:'post',
                    data:{
                        'article_id':'{{ article_obj.pk }}',
                        'is_up':isUp,
                        'csrfmiddlewaretoken':'{{ csrf_token }}'
                    },
                    success:function (args) {
                            if(args.code == 1000){
                                $('#digg_tips').text(args.msg)
                                // 将前端的数字加一
                                // 先获取到之前的数字
                                let oldNum = $div.children().text();  // 文本 是字符类型
                                // 易错点
                                $div.children().text(Number(oldNum) + 1)  // 字符串拼接了 1+1 = 11  11 + 1 = 111
                            }else{
                                $('#digg_tips').html(args.msg)
                            }
                    }
                })
            })
        </script>

    文章评论

    """
    我们先写根评论
    再写子评论
    ​
    点击评论按钮需要将评论框里面的内容清空
    ​
    根评论有两步渲染方式
        1.DOM临时渲染
        2.页面刷新render渲染
    ​
    子评论
        点击回复按钮发生了几件事
            1.评论框自动聚焦
            2.将回复按钮所在的那一行评论人的姓名
                @username
            3.评论框内部自动换行
        
    根评论子评论都是点击一个按钮朝后端提交数据的
        parent_id
    根评论子评论区别在哪?
        parent_id
    """
     

     

     

     

  • 相关阅读:
    共享内存
    利用消息队列实现ECHO_SRV
    LINUX学习:System V消息队列
    linux:利用socketpair来在进程间传递描述符
    react传参
    ajax、axios、fetch
    js 深拷贝和浅拷贝实现
    css----px、rem、em、vw、vh、vm
    Sass、Less 和 Stylus区别
    箭头函数和普通函数对比
  • 原文地址:https://www.cnblogs.com/lucky-cat233/p/13101350.html
Copyright © 2011-2022 走看看