• BBS项目架构 之建表关系 注册 登录 修改头像 个人站点左侧边框,个人站点搭建 修改头像时 立马显示


    BBS项目架构

    数据库设计

    用户表(用的是auth_user那张表,通过自定义继承AbstractUser)

    phone  电话
    
    avatar   头像
    
    create_time    创建时间
    
    #外键
    
    blog                    一对一个人站点表  

    个人站点表(副标题,摘要)

    site_name            站点名
    
    site_title                名言警句
    
    site_theme            样式  

    标签表

    name            标签名
    
    #外键
    
    blog    一对多个人站点            每个站点含有多个标签

    分类表

    name        分类名
    
    #外键
    
    blog           一对多个站点            每个站点含有多个标签

    文章表

    title                        文章标题
    desc                        文章摘要
    content                    文章内容
    create_time                文章创建时间
    
    
    #外键
    blog            一对多个人站点        一个站点下可以有多篇文章
    
    tag            多对多标签            一个文章有多个标签,一个标签可以对应多篇文章
    
    category        一对多分类        一个分类下面有多篇文章
    
    
    #普通字段
    #数据库设计优化(*******)设置这些就不用于点赞点踩表中查询数据 了,减少数据库查询量
    #开一个事务,当你操作点赞点踩表的时候,下面这些数据也会变化
    评论数        comment_num        普通字段
    点赞数         up_num                 普通字段
    点踩数         down_num              普通字段
                                

    点赞点踩表

    user                    一对多用户表            一个评论是一个用户写的,一个用户能写多个评论
    
    article                一对多文章表
    
    comment            评论内容
    
    create_time          创建时间
    
    parent                 一对多评论表(自关联)     父评论的id 如果有值说明你是子评论  如果没有值说明你是父评论
          

    评论表

    # 根评论和子评论分析
    id   user  articel   content                   commit
    1     1     1         写的真好                     null
    2     1     2         写的真烂                     null
    3     2     2         你放屁,人家写的很好            2
    4     1     2         你怎么骂人呢?                 3
    5     2     2         就骂你怎么了                   4
    6     3     2         你这个嘴太碎了                 2
    7     4     2         碎嘴子                        2
    

      

    需要创建的表

    from django.db import models
    
    from django.contrib.auth.models import AbstractUser
    
    
    class UserInfo(AbstractUser):
        phone = models.CharField(max_length=32)
        # upload_to文件上传以后存放的路径
        # FileField本质是varchar类型
        # 坑()
        avatar = models.FileField(upload_to='avatar/', default='avatar/default.png')
        blog = models.OneToOneField(to='Blog',on_delete=models.CASCADE)
    
    
    class Blog(models.Model):
        site_title = models.CharField(max_length=32)
        site_name = models.CharField(max_length=32)
        # 每个人样式不同(文件地址)
        site_style = models.CharField(max_length=32)
    
    
    class Tag(models.Model):
        name = models.CharField(max_length=32)
        blog = models.ForeignKey(to='Blog',on_delete=models.CASCADE)
    
    
    class Category(models.Model):
        name = models.CharField(max_length=32)
        blog = models.ForeignKey(to='Blog',on_delete=models.CASCADE)
    
    
    class Article(models.Model):
        title = models.CharField(max_length=32)
        desc = models.CharField(max_length=128)
        # 大文本
        content = models.TextField()
        create_time = models.DateTimeField(auto_now_add=True)
    
        # 关联关系
        blog = models.ForeignKey(to='Blog',on_delete=models.CASCADE)
        category = models.ForeignKey(to='Category',on_delete=models.CASCADE)
        # 多对多关系
        tag = models.ManyToManyField(to='Tag', through='TagToArticle', through_fields=('article', 'tag'))
    
    
    class TagToArticle(models.Model):
        tag = models.ForeignKey(to='Tag',on_delete=models.CASCADE)
        article = models.ForeignKey(to='Article',on_delete=models.CASCADE)
    
    
    class UpAndDown(models.Model):
        user = models.ForeignKey(to='UserInfo',on_delete=models.CASCADE)
        article = models.ForeignKey(to='Article',on_delete=models.CASCADE)
        # 实质存的时候,是0和1
        is_up = models.BooleanField()
        create_time = models.DateTimeField(auto_now_add=True)
    
    
    class Commit(models.Model):
        user = models.ForeignKey(to='UserInfo',on_delete=models.CASCADE)
        article = models.ForeignKey(to='Article',on_delete=models.CASCADE)
        content = models.CharField(max_length=256)
        create_time = models.DateTimeField(auto_now_add=True)
    
        # 存父评论的id号
        # commit_id=models.IntegerField()
        # commit=models.ForeignKey(to='Commit')
        # 自关联(不能叫表明小写)
        commit_id=models.ForeignKey(to='self',on_delete=models.CASCADE)
    
    
    
        # 踩了两个坑
        avatar = models.FileField(upload_to='avatar/', default='avatar/default.png')
        commit_id=models.ForeignKey(to='self',on_delete=models.CASCADE)
        
       # 迁移(两条命令) 

    注册form组件编写

    1 用户名,密码,            修改个人信息:邮箱,手机号,头像
    2 用户名,密码,邮箱,头像
    from django import forms
    from django.forms import widgets
    
    from blog import models
    from django.forms import ValidationError
    
    
    class RegisterForm(forms.Form):
        username = forms.CharField(required=True, max_length=18, min_length=3, label='用户名',
                                   error_messages={'required': '该字段必填',
                                                   'max_length': '最大长度为18',
                                                   'min_length': '最短为3'},
                                   widget=widgets.TextInput(attrs={'class': 'form-control'}))
        password = forms.CharField(required=True, max_length=18, min_length=3, label='密码',
                                   error_messages={'required': '该字段必填',
                                                   'max_length': '最大长度为18',
                                                   'min_length': '最短为3'},
                                   widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
        re_password = forms.CharField(required=True, max_length=18, min_length=3, label='确认密码',
                                      error_messages={'required': '该字段必填',
                                                      'max_length': '最大长度为18',
                                                      'min_length': '最短为3'},
                                      widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
        email = forms.EmailField(required=True, label='邮箱',
                                 error_messages={'required': '该字段必填'},
                                 widget=widgets.EmailInput(attrs={'class': 'form-control'}))
    
        # 用户名如果存在了,就不能注册
        def clean_username(self):
            username = self.cleaned_data.get('username')
            # 去数据库查询
            user = models.UserInfo.objects.filter(username=username).count()
            if user:  # 不合法
                raise ValidationError('用户名已经存在')
            else:
                return username
    
        # 校验两次密码是否一致
        def clean(self):
            password = self.cleaned_data.get('password')
            re_password = self.cleaned_data.get('re_password')
            if re_password == password:
                return self.cleaned_data
            else:
                raise ValidationError('两次密码不一致')

    注册功能页面搭建<!DOCTYPE html>

    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
        <script src="/static/jquery-3.3.1/jquery-3.3.1.min.js"></script>
        <title>注册</title>
    </head>
    <body>
    <div class="container-fluid">
        <div class="row">
            <h1 class="text-center">注册功能</h1>
            <div class="col-md-6 col-md-offset-3">
    
                <form id="form">
                {% csrf_token %}
                    {% for foo in form %}
                        <div class="form-group">
                            <label for="{{ foo.auto_id }}">{{ foo.label }}</label>
                            {{ foo }}
                        </div>
                    {% endfor %}
                    <div class="form-group">
                        <label for="id_myfile">头像
                            <img src="/static/img/default.png" alt="" id="id_img" height="80" width="80"
                                 style="margin-left: 10px">
                        </label>
    
                        <input type="file" name="myfile" id="id_myfile" style="display: none">
                    </div>
                    <div class="text-center">
                        {#注意这个坑#}
                        <input type="button" value="注册" id="id_submit" class="btn btn-danger">
                    </div>
                </form>
            </div>
        </div>
    </div>
    </body>
    
    <script>
        //放文件的标签发生变化,我们把文件搞出来,放到img标签中
        $("#id_myfile").change(function () {
            //借助于文件阅读器
            const filereader = new FileReader()
            //把图片读到filereader对象中
            //$('#id_myfile')[0].files[0]
            filereader.readAsDataURL($('#id_myfile')[0].files[0])
            //$('#id_img').attr('src','https://account.cnblogs.com/images/registersideimg.png')
            //$('#id_img').attr('src',filereader.result) //这样不行,文件没读完
            filereader.onload = function () {
                //文件完全读到文件阅读器以后,再执行
                $('#id_img').attr('src', filereader.result)
            }
        })
    
        $("#id_submit").click(function () {
            var formdata = new FormData()
            formdata.append('avatar', $('#id_myfile')[0].files[0])  #取文件对象
            //第一种方式:
            /*
            formdata.append('username', $('#id_name').val())
            formdata.append('password', $('#id_password').val())
            formdata.append('re_password', $('#id_re_password').val())
            formdata.append('email', $('#id_email').val())
             */
            //第二种方式:
            var ser = $('#form').serializeArray()
            //[{name:name,value:lqz}, {name:password],value:123}, {name:re_password],value:123}, {name:email],value:123@qq.com}]
            //console.log(ser)
    
            $.each(ser, function (k, v) {
                //console.log(v.name)
                //console.log(v.value)
                formdata.append(v.name, v.value)
            })
    $.ajax({ url: '/register/', method: 'post', processData: false, contentType: false, data: formdata, success: function (data) { if (data.code == 100) { console.log(data.msg) //js控制的跳转 location.href=data.url } else { //有错误,需要渲染页面 } } }) }) </script> </html>

    头像实时显示

    $("#id_myfile").change(function () {
        //借助于文件阅读器
        const filereader = new FileReader()
        //把图片读到filereader对象中
        //$('#id_myfile')[0].files[0]
        filereader.readAsDataURL($('#id_myfile')[0].files[0])
        //$('#id_img').attr('src','https://account.cnblogs.com/images/registersideimg.png')
        //$('#id_img').attr('src',filereader.result) //这样不行,文件没读完
        filereader.onload = function () {
            //文件完全读到文件阅读器以后,再执行
            $('#id_img').attr('src', filereader.result)
        }
    }) 
    头像修改后端
    第一种方法:(比较麻烦,需要再自己手动操作存一次文件,用update存,只是将文件的路径存进了avatar并没有将图片文件存进去)
    def
    chang_img(request): res = {'code': 100, 'msg': '修改成功'} print(11111) file = request.FILES.get('avatar') if file:
          #存头像到文件夹 img
    =Image.open(file) img.save('media/avatar/'+file.name) file = 'avatar/' + file.name print(file, type(file)) obj=models.UserInfo.objects.filter(username=request.user.username).update(avater=file) return JsonResponse(res) res['code'] = 101 res['msg'] = '修改失败' return JsonResponse(res)


    第二种方法:直接保存图片对象即可
    def update_head(request):
    if request.method == 'GET':
    return render(request, 'backend/update_head.html')
    else:
    head = request.FILES.get('myfile')
    # 方式一
    request.user.avatar = head
    request.user.save()
    return redirect('/')
    
    

    头像修改前端

      $('#id_myfile').change(function () {
            //借助于阅读器
            const filereader = new FileReader()
            //把图片读到filereader对象中
            filereader.readAsDataURL($('#id_myfile')[0].files[0])
            filereader.onload = function () {
                console.log(1111112222)
                //文件完全读到文件阅读器以后再执行
                $('#id_img').attr('src', filereader.result)
            }
        })
        $('#changeimg').click(function () {
            var formdata = new FormData()
            formdata.append('avatar', $('#id_myfile')[0].files[0])
            console.log(333333)
            formdata.append('csrfmiddlewaretoken', '{{ csrf_token }}')
            console.log(formdata)
            $.ajax({
    
                url: '/chang_img/',
                method: 'post',
                data: formdata,
                processData: false,
                contentType: false,
                success: function (data) {
                    if (data.code === 100) {
                        alert(data.msg)
                    } else {
                        alert(data.msg)
                    }
    
    
                }
            })


    注册功能     利用form组件来校验登录信息是否正确,并且渲染页面

    
    

    1 文件输入框设置了id='myfile'和隐藏文件输入框,在lable标签设置for='myfile',那么点击头像两个字就弹出文件输入框的效果

    
    
    <label for="myfile">头像
    设置默认头像图片
    <img src="/static/img/default.jpg" alt="" height="80" style="margin-left: 20px" id="img">
    </label>
    <input type="file" id="myfile" style="display: none">   #文件输入框
    
    
    

     







    注册功能完成(后端)
    def register(request):
        if request.method == 'GET':
            form = RegisterForm()
            return render(request, 'register.html', context={'form': form})
        elif request.method == 'POST':
            # 校验数据是否合法
            res = {'code': 100, 'msg': '注册成功'}
            form = RegisterForm(data=request.POST)
            if form.is_valid():
    
                # 保存到数据库
                data = form.cleaned_data  # {username:lqz,password:123,re_password:123,email:3@qq.com}
                data.pop('re_password')# {username:lqz,password:123,email:3@qq.com}
                file=request.FILES.get('avatar')
                if file:
                    data['avatar']=file # {username:lqz,password:123,email:3@qq.com,'avatar':文件对象}
                print(data)
                models.UserInfo.objects.create_user(**data)
                # res['url']='/index/'
                res['url']='http://www.baidu.com'
                '''
                FileField自动干了这个事
                with open('media/avatar/%s'%file.name,'wb') as f:
                    for line in file:
                        f.write(line)
                path='media/avatar/%s'%file.name
            
                '''
                # models.UserInfo.objects.create_user(username=username,password=password,email=email,avatar=path)
                # 返回,会被ajax接收到
                return JsonResponse(res)
            else:
                # 数据校验不通过
                res['code'] = 101  # 101表示注册失败
                res['msg'] = '数据验证失败'
                res['error'] = form.errors
                return JsonResponse(res)

    前端

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <script src="/static/jquery-3.3.1/jquery-3.3.1.min.js"></script>
    <title>注册</title>
    </head>
    <body>
    <div class="container-fluid">
    <div class="row">
    <h1 class="text-center">注册功能</h1>
    <div class="col-md-6 col-md-offset-3">

    <form id="form">
    {% csrf_token %}
    {% for foo in form %}
    <div class="form-group">
    <label for="{{ foo.auto_id }}">{{ foo.label }}</label>
    {{ foo }}
    </div>
    {% endfor %}
    <div class="form-group">
    <label for="id_myfile">头像
    <img src="/static/img/default.png" alt="" id="id_img" height="80" width="80"
    style="margin-left: 10px">
    </label>

    <input type="file" name="myfile" id="id_myfile" style="display: none">
    </div>
    <div class="text-center">
    {#注意这个坑#}
    <input type="button" value="注册" id="id_submit" class="btn btn-danger">
    </div>
    </form>
    </div>
    </div>
    </div>
    </body>

    <script>
    //放文件的标签发生变化,我们把文件搞出来,放到img标签中
    $("#id_myfile").change(function () {
    //借助于文件阅读器
    const filereader = new FileReader()
    //把图片读到filereader对象中
    //$('#id_myfile')[0].files[0]
    filereader.readAsDataURL($('#id_myfile')[0].files[0])
    //$('#id_img').attr('src','https://account.cnblogs.com/images/registersideimg.png')
    //$('#id_img').attr('src',filereader.result) //这样不行,文件没读完
    filereader.onload = function () {
    //文件完全读到文件阅读器以后,再执行
    $('#id_img').attr('src', filereader.result)
    }
    })

    $("#id_submit").click(function () {
    var formdata = new FormData()
    formdata.append('avatar', $('#id_myfile')[0].files[0])
    //第一种方式:
    /*
    formdata.append('username', $('#id_name').val())
    formdata.append('password', $('#id_password').val())
    formdata.append('re_password', $('#id_re_password').val())
    formdata.append('email', $('#id_email').val())
    */
    //第二种方式:(推荐)
    var ser = $('#form').serializeArray()
    相当于做了下面的事
    //[{name:name,value:lqz}, {name:password],value:123}, {name:re_password],value:123}, {name:email],value:123@qq.com}]
    //console.log(ser)

    $.each(ser, function (k, v) {
    //console.log(v.name)
    //console.log(v.value)
    formdata.append(v.name, v.value)
    })

    $.ajax({
    url: '/register/',
    method: 'post',
    processData: false,
    contentType: false,
    data: formdata,
    success: function (data) {
    if (data.code == 100) {
    console.log(data.msg)
    //js控制的跳转
    location.href = data.url
    } else {
    //有错误,需要渲染页面
    }
    }

    })


    })

    </script>
    </html>







     

    登录功能实现

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录页面</title>
        {% load static %}
        <script src="{% static 'jquery-3.3.1/jquery-3.3.1.min.js' %}"></script>
        <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
    
        {#    <script src="jQuery.js"></script>#}
    </head>
    <body>
    <div class="container-fluid">
        <div class="row">
            <h1 class="text-center">登录功能</h1>
            <div class="col-md-6 col-md-offset-3">
                <form action="">
                    {% csrf_token %}
                    <div class="form-group">
                        <lable for=""> 用户名</lable>
                        <input type="text" name="username" class="form-control">
                    </div>
                    <div class="form-group">
                        <lable> 密码</lable>
                        <input type="text" name="password" class="form-control">
                    </div>
                    <div class="form-group">
                        <lable> 验证码</lable>
                        <div class="row">
                            <div class="col-md-4">
    
    
                                <input type="text" name="valid_code" class="form-control">
                            </div>
                            <div class="col-md-6">
                                <img src="/get_valid/" alt="" height="40" width="400" id="id_valid_code">
                            </div>
                        </div>
                    </div>
                    <div class="text-center">
                        <input type="button" value="登录" id="id_submit" class="btn btn-danger">
                        <span class="error text-danger" style="margin-left: 10px"> </span>
                    </div>
                </form>
            </div>
        </div>
    </div>
    
    
    </body>
    <script>
        $('#id_valid_code').click(function () {
            var  url = $('#id_valid_code')[0].src
            $('#id_valid_code')[0].src = url+'?'
    
        })
    
        $('#id_submit').click(function () {
            $.ajax({
                url:'/login/',
                method:'post',
                data:{
                    {#通过name取值#}
                    'username':$('[name=username]').val(),
                    'password':$('[name=password]').val(),
                    'valid_code':$('[name=valid_code]').val(),
                    'csrfmiddlewaretoken':'{{ csrf_token }}',
                },
    
    
                success:function (data) {
                    console.log(data)
                    if (data.code === '100'){
                        location.href=data.url
                    }else {
                        $('.error').html(data.msg)
                    }
                }
            })
        })
    </script>
    </html>

    后端

    def login(request):
        if request.method == 'GET':
            return render(request, 'login.html')
        else:
            print(111111111111)
            res = {'code':'100','msg':None}
            username = request.POST.get('username')
            password = request.POST.get('password')
            valid_code = request.POST.get('valid_code')
            if valid_code.upper() == request.session.get('valid_code').upper():
                user = auth.authenticate(username=username,password=password)
                if user:
                    #验证成功后一定要写这一句,这样在任何地方都可以拿到request.user
                    auth.login(request,user)
                    res['msg']='登录成功'
                    res['url']='/index/'
    
                else:
                    res['code']='101'
                    res['msg']='用户名或密码错误'
            else:
                res['code']='102'
                res['msg']='验证码错误'
            print(22222)
            return JsonResponse(res)

    首页代码轮播图

      <div class="middle_content col-md-7">
                    <div class="lbt">
                        <div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
                            <!-- Indicators -->
                            <ol class="carousel-indicators">
                                <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
                                <li data-target="#carousel-example-generic" data-slide-to="1"></li>
                                <li data-target="#carousel-example-generic" data-slide-to="2"></li>
                            </ol>
    
                            <!-- Wrapper for slides -->
                            <div class="carousel-inner" role="listbox">
                                <div class="item active">
    
                                    <a href="{{ ll.0.url }}"><img
                                            src="{{ ll.0.img_url }}"
                                            alt="..." class="img"></a>
                                    <div class="carousel-caption">
                                        {{ll.0.msg}}
                                    </div>
    
                                </div>
                                <div class="item">
                                    <a href="http://www.mzitu.com"><img
                                            src="{{ ll.1.img_url }}"
                                            alt="..." class="img"></a>
                                    <div class="carousel-caption">
                                        {{ll.1.msg}}
                                    </div>
                                </div>
                                <div class="item">
                                    <a href="{{ll.1.url}}"><img
                                            src="{{ ll.2.img_url }}"
                                            alt="..." class="img" height='802px' width="306px"></a>
                                    <div class="carousel-caption">
                                        点我看美女
                                    </div>
                                </div>
                            </div>
    
                            <!-- Controls -->
                            <a class="left carousel-control" href="#carousel-example-generic" role="button"
                               data-slide="prev">
                                <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
                                <span class="sr-only">Previous</span>
                            </a>
                            <a class="right carousel-control" href="#carousel-example-generic" role="button"
                               data-slide="next">
                                <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
                                <span class="sr-only">Next</span>
                            </a>
                        </div>
                    </div>

    首页文章展示代码

    <div class="article">
                        {% for article in article_list %}
                            <hr>
                            <div class="media">
                                <h4 class="media-heading"><a href="/{{article.blog.userinfo.username}}/article/{{ article.id }}">{{ article.title }}</a></h4>
                                <div class="media-heading">{{ article.desc }}
                                </div>
                                <div class="media-left">
                                    <a href="">
                                        <img class="media-object" src="/media/{{ article.blog.userinfo.avater }}" alt="..."
                                             width="60"
                                             height="60">
                                    </a>
                                </div>
                                <div class="article_bottom"><span><a href="">{{ article.blog.userinfo.username }}</a></span>
                                    <span>{{ article.create_time | date:'Y-m-d H-i-s' }}</span>
                                    <span><i class="fa fa-stethoscope fa-lg"></i>&nbsp&nbsp&nbsp{{ article.up_num }} &nbsp&nbsp&nbsp</span><span
                                            class="glyphicon glyphicon-comment"><i
                                            class="fa fa-flickr1 fa-lg"> </i> {{ article.commit_num }}
    
                                </span>
    
                                </div>
    
                            </div>
    
                        {% endfor %}
    
    
                    </div>




    侧边栏左侧inclusion_tag

    # 步骤
        -在app下创建一个包,templatetags
        -任意新建一个py文件my_tag.py
        -导入library
        register = library.Library()
        -写一个函数,使用inclusion_tag装饰
        @register.inclusion_tag('left.html')
    def left(username):
        user = models.UserInfo.objects.filter(username=username).first()
        res_category = models.Category.objects.filter(blog=user.blog).annotate(num=Count('article__id')).values_list(
            'name', 'num', 'id')
        res_tag = models.Tag.objects.filter(blog=user.blog).annotate(num=Count('article__id')).values_list('name',
                                                                                                           'num', 'id')
        res_month = models.Article.objects.filter(blog=user.blog).annotate(month=TruncMonth('create_time')).values(
            'month').annotate(c=Count('id')).order_by('-month').values_list('month', 'c')
    
        return {'name':username,'res_category': res_category, 'res_tag': res_tag, 'res_month': res_month}
        
        -写一个模板
        <div>
        <div class="panel panel-danger">
            <div class="panel-heading">
                <h3 class="panel-title">我的标签</h3>
            </div>
            <div class="panel-body">
                {% for tag in res_tag %}
                    <p><a href="/{{ name }}/tag/{{ tag.2 }}.html">{{ tag.0 }}({{ tag.1 }})</a></p>
                {% endfor %}
            </div>
        </div>
        <div class="panel panel-info">
            <div class="panel-heading">
                <h3 class="panel-title">随笔分类</h3>
            </div>
            <div class="panel-body">
                {% for category in res_category %}
    
                    <p><a href="/{{ name }}/category/{{ category.2 }}.html">{{ category.0 }}({{ category.1 }})</a></p>
                {% endfor %}
    
    
            </div>
        </div>
        <div class="panel panel-info">
            <div class="panel-heading">
                <h3 class="panel-title">随笔档案</h3>
            </div>
            <div class="panel-body">
                {% for month in res_month %}
                    <p>
                        <a href="/{{ name }}/archive/{{ month.0|date:'Y/m' }}.html">{{ month.0|date:'Y年m月' }}({{ month.1 }})</a>
                    </p>
                {% endfor %}
            </div>
        </div>
    </div>
    
        -使用,在指定的位置
             {% load mytag %}
             {% left name %}
    
        

    个人站点(前端):

     1 {% extends 'base.html' %}
     2 
     3 {% block title %}
     4 {{ user.username }}-博客园
     5 {% endblock %}
     6 {% block content %}
     7 
     8     <div class="article">
     9         {% for article in article_list %}
    10             <hr>
    11             <div class="media">
    12                 <h4 class="media-heading"><a href="/{{ user.username }}/article/{{ article.id }}.html">{{ article.title }}</a></h4>
    13 
    14                 <div class="media-body">
    15                     {{ article.desc }}
    16                 </div>
    17                 <div class="article_bottom pull-right">
    18                     <span>posted@</span>
    19                     <span>{{ article.create_time|date:'Y-m-d H-i-s' }}</span>
    20                     <span>{{ user.username }}</span>
    21                     <span><i class="fa fa-stethoscope fa-lg"></i> {{ article.up_num }}</span><span
    22                         class="glyphicon glyphicon-comment"><i
    23                         class="fa fa-flickr1 fa-lg"></i> {{ article.commit_num }}</span>
    24                     <span><a href="">编辑</a></span>
    25                 </div>
    26             </div>
    27         {% endfor %}
    28 
    29 
    30     </div>
    31 {% endblock %}

    个人站点后端

    def site(request, name, **kwargs):
        # 分三种情况(根据标签过滤,根据分类过滤,根据时间过滤)
        user = models.UserInfo.objects.filter(username=name).first()
        if user:
            article_list = user.blog.article_set.all()
            # 根据不同情况对article_list进行过滤,article_list是queryset对象,可以继续filter
            query = kwargs.get('query', None)
            if query == 'category':  # 说明走的是过滤的路由
                condition = kwargs.get('condition')
                article_list = article_list.filter(category_id=condition)
            elif query == 'tag':
                condition = kwargs.get('condition')
                article_list = article_list.filter(tag__id=condition)
            elif query == 'archive':
                year, month = kwargs.get('condition').split('/')  # 2020/09
                article_list = article_list.filter(create_time__year=year, create_time__month=month)
    
            return render(request, 'site.html', locals())
        else:
            return render(request, 'error.html')
  • 相关阅读:
    第九篇装饰器基本原理
    第八篇迭代器协议和生产器
    python第六篇文件处理类型
    Python开发【第十篇】:模块
    习题练习
    2.2.6 集合
    第七篇 python基础之函数,递归,内置函数
    Python开发【第五篇】:Python基础之杂货铺
    Python开发【第四篇】:Python基础之函数
    详解CSS position属性
  • 原文地址:https://www.cnblogs.com/ltyc/p/13885804.html
Copyright © 2020-2023  润新知