首页 > 其他分享 >BBS-博客首页

BBS-博客首页

时间:2023-05-14 21:24:19浏览次数:46  
标签:登录 request 博客 密码 首页 password BBS 路由

目录

重点功能:

  • 修改密码弹出模态框
  • 展示出所有文章
  • 文章旁边可以显示作者头像

一、添加路由

在urls.py中添加,

导入模块

from django.conf.urls import url
from django.contrib import admin
from app01 import views

from django.views.static import serve
from django.conf import settings

1、首页路由

    # 首页相关
    url(r'^home/$', views.home),  # 首页路由

2、修改密码路由

    url(r'^set_password/$', views.set_password),  # 修改密码路由

3、退出登录路由

    url(r'^logout/$', views.logout),  # 退出登录路由

4、个人头像路由

    # 如果你想访问media文件夹下的内容,必须开设一个接口对外访问
    url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),

首页

首页前端

首页前端步骤

总步骤:

1.导航条
登录和未登录导航栏右边是两种形式,加个判断
    {% if  request.session.username %}
    <!-- 动态获取用户名 -->
    {% else %}
    注册登录两个标签
    {% endif %}
2.剩下布局分成3份:2,8,2
3.左右两边先用面板占位置
4.中间是文章内容,复制媒体对象先用文字和默认图片调整好样式
5.首页数据展示
6.图片上传到media文件夹中,配置上传路径(settings中配置路径),增加访问media接口(路由配置)

首页前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BBS仿博客园搭建</title>
    {#    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css">#}
    {#    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>#}
    {#    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css"></script>#}
    {% load static %}
    <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    <script src="{% static 'js/jquery.min.js' %}"></script>
    <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>

</head>
<body>
{# 导航条开始 #}
<nav class="navbar navbar-inverse">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">仿博客园作业(BBS)</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">首页 <span class="sr-only">(current)</span></a></li>
                <li><a href="#">新闻</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                       aria-expanded="false">其他选择 <span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">专区</a></li>
                        <li><a href="#">闪存</a></li>
                        <li><a href="#">班级</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">怀旧</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">发现</a></li>
                    </ul>
                </li>
            </ul>
            <form class="navbar-form navbar-left">
                <div class="form-group">
                    <input type="text" class="form-control" placeholder="Search">
                </div>
                <button type="submit" class="btn btn-default">搜索</button>
            </form>
            <ul class="nav navbar-nav navbar-right">
                {% if  request.session.username %} <!-- 用户登录显示用户名,失败显示注册登录样式 -->
                    <li><a href="#">{{ request.session.username }}</a></li> <!-- 动态获取用户名 -->
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                           aria-expanded="false">更多选择 <span class="caret"></span></a>
                        <ul class="dropdown-menu">
                            <li><a href="#" data-toggle="modal" data-target=".bs-example-modal-lg">修改密码</a></li>
                            <li><a href="#">后台管理</a></li>
                            <li><a href="/logout/">退出登录</a></li>
                        </ul>
                    </li>
                {% else %}
                    <li><a href="/register/">注册</a></li><!-- 点击注册跳转到注册页面 -->
                    <li><a href="/login/">登录</a></li>
                {% endif %}
            </ul>

            {# 修改密码开始 #}
            <div><!-- 点击修改密码,弹出模态框 -->
                <div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog"
                     aria-labelledby="myLargeModalLabel">
                    <div class="modal-dialog modal-lg" role="document">
                        <div class="modal-content">
                            <h1 class="text-center">修改密码</h1>
                            <div class="row">
                                <div class="col-md-8 col-md-offset-2">
                                    <form action="">
                                        <div class="form-group">
                                            <label for="username">用户名:</label>
                                            <input type="text" id="username" class="form-control" disabled
                                                   value="{{ request.session.username }}"><!-- 用户名显示并且禁用 -->
                                        </div>
                                        <div class="form-group">
                                            <label for="old_password">原密码:</label>
                                            <input type="password" id="old_password" class="form-control">
                                        </div>
                                        <div class="form-group">
                                            <label for="new_password">新密码:</label>
                                            <input type="password" id="new_password" class="form-control">
                                        </div>
                                        <div class="form-group">
                                            <label for="re_password">确认密码:</label>
                                            <input type="password" id="re_password" class="form-control">
                                        </div>
                                        {# <input type="button" class="btn btn-success" value="提交">#}
                                        <div  class="pull-right">
                                            <button class="btn btn-success">提交</button>
                                        </div>
                                        <!-- button放在form表单中有自动提交的事件,下面script中需要阻止后续事件的执行 -->
                                        <br>
                                        <br>
                                        <br>
                                    </form>
                                    {# 修改密码结束 #}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>
{# 导航条结束 #}

<!-- 剩下的布局分成3份 -->
<div class="container-fluid">
    <div class="row"><!-- 底下的分成3份,2,8,2分 -->
        <div class="col-md-2">
            <!-- 面板先占位置 -->
            <div class="panel panel-primary">
                <div class="panel-heading">Panel heading without title</div>
                <div class="panel-body">Panel content</div>
                <div class="panel-body">Panel content</div>
                <div class="panel-body">Panel content</div>
                <div class="panel-body">Panel content</div>
                <div class="panel-body">Panel content</div>
                <div class="panel-body">Panel content</div>
            </div>
            <div class="panel panel-danger">
                <div class="panel-heading">Panel heading without title</div>
                <div class="panel-body">Panel content</div>
                <div class="panel-body">Panel content</div>
            </div>
        </div>
        <div class="col-md-8">
            <!-- 中间是文章内容,使用媒体对象 -->
            <ul class="media-list">
                {% for article in article_list %}<!-- 循环所有文章对象的列表 -->
                    <li class="media">
                        <h4 class="media-heading"><a href="">{{ article.title }}</a></h4><!-- 文章标题 -->
                        <div class="media-left">
                            <a href="#">
                                <!-- 显示文章列表中的avatar,使用media文件夹 -->
                                <!-- 文章对象.站点表(反向).用户表(反向) -->
                                <img class="media-object" src="/media/{{ article.blog.userinfo.avatar }}" alt="..." style="width: 70px;"><!-- 头像 -->
                            </a>
                        </div>
                        <div class="media-body">{{ article.desc }}</div><!-- 文章摘要 -->
                        <br>
                        <div>
                            <!-- xiezhr 2023-05-10 08:04  1   0 121 -->
                            <!-- 文章对象.站点表(反向).用户表(反向) -->
                            <span><a href="">{{ article.blog.userinfo.username }}</a></span>&nbsp;&nbsp;<!-- 用户名 -->
                            <span>{{ article.create_time|date:'Y-m-d' }}&nbsp;&nbsp;</span><!-- 注册时间 -->
                            <span><span class="glyphicon glyphicon-thumbs-up"></span>({{ article.up_num }})&nbsp;&nbsp;</span><!-- 点赞数 -->
                            <span><span class="glyphicon glyphicon-thumbs-down"></span>({{ article.down_num }})&nbsp;&nbsp;</span><!-- 点踩数 -->
                            <span><span class="glyphicon glyphicon-comment"></span>({{ article.comment_num }})&nbsp;&nbsp;</span><!-- 评论数 -->
                        </div>
                        <hr>
                    </li>
                {% endfor %}
            </ul>
        </div>
        <div class="col-md-2">
            <div class="panel panel-primary">
                <div class="panel-heading">Panel heading without title</div>
                <div class="panel-body">
                    Panel content
                </div>
            </div>
            <div class="panel panel-primary">
                <div class="panel-heading">Panel heading without title</div>
                <div class="panel-body">
                    Panel content
                </div>
            </div>
            <div class="panel panel-primary">
                <div class="panel-heading">Panel heading without title</div>
                <div class="panel-body">
                    Panel content
                </div>
            </div>
        </div>
    </div>
</div>

<!-- 引入layer文件 -->
{#<script src="/static/layer/layer.js"></script>#}
<script src="/static/layer/layer.js"></script>
<script>
    // 修改密码提交事件
    $(".btn").click(function (e) {
        e.preventDefault();  // 阻止后续事件执行
        // 1. 获取参数
        var old_password = $("#old_password").val();
        var new_password = $("#new_password").val();
        var re_password = $("#re_password").val();

        // 2. 验证参数
        //if (!old_password) {
        //    layer.msg('原始密码不能为空');
        //    return;
        //}
        //if (!new_password) {
        //    layer.msg('新密码不能为空');
        //    return;
        //}
        //if (!re_password) {
        //    layer.msg('确认密码不能为空');
        //    return;
        //}

        // 3. 发起ajax请求,把密码输入的数据提交到后端
        $.ajax({
            url: '/set_password/',  // url不能省略,朝修改密码的路由提交post请求
            type: 'post',
            data: {
                old_password: old_password,
                new_password: new_password,
                re_password: re_password,
                csrfmiddlewaretoken: '{{ csrf_token }}'
            },
            success: function (res) {
                if (res.code == 200) {
                    // icon: 1
                    layer.msg(res.msg, {}, function () {
                        {#console.log(msg);#}
                        location.reload();  // 输入密码成功后刷新页面,或者也可以跳转到登录页面
                        // location.href = res.url;
                    })
                } else {
                    {#console.log(msg);#}
                    layer.msg(res.msg);
                }
            }
        })
    })
</script>
</body>
</html>

首页后端

后端代码

Django的分页器:https://www.cnblogs.com/zjyao/p/17378488.html

def home(request):
    """首页搭建"""
    # 展示所有的文章列表,查出文章表对象
    article_list = models.Article.objects.all()
    # print(article_list)  # QuerySet对象:[对象1,对象2]
    """文章过多的情况下,可以考虑添加分页器"""
    return render(request, 'home.html', locals())

前端重点

前端数据展示逻辑

5.首页数据展示
    文章标题
    图片:展示用户头像,文章查用户
    # 文章--> 站点(正向)--> 用户(反向)--> 点avatar
    文章摘要
    作者:文章查作者
    # 文章--> 站点(正向)--> 用户(反向)--> 点username
    文章创建时间,过滤器格式化
    文章点赞数
    文章点踩数
    文章评论数

文章旁的图片展示

6.图片上传到media文件夹中,配置上传路径(settings中配置路径),增加访问media接口(路由配置)
    6.1 settings中做配置,配置上传路径
    6.2 增加路由,增加访问接口 
    6.3 改变一下首页前端图片标签中的src地址,把/media/加上

图片展示不正常?

没有开设avater接口。项目中静态文件想要展示,需要开设接口的。图片文件,我们一般不开设avater接口,新开设一个media文件夹,把用户上传的图片单独防止在这个文件夹中。

1.settings中做配置,配置上传路径

# 只要配置了这句话,以后再上传图片的话,就会上传到这个文件夹下面去
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

2.增加路由,增加访问接口 # 暴漏该目录

from django.views.static import serve
from django.conf import settings

# 如果你想访问media文件夹下的内容,必须开设一个接口对外访问
url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),  # 固定写法

修改密码

点击修改密码中弹出模态框

修改密码前端步骤

1.在修改密码的a标签中增加两个属性
data-toggle="modal" data-target=".bs-example-modal-lg"
2.模态框中第一个div标签的
class="modal fade"中增加一个类:bs-example-modal-lg
3.增加form表单数据框
	用户名显示并且禁用
	button在form表单自带提交事件,ajax中需要阻止后续事件的执行
4.ajax提交数据到后端re_password路由中
	4.1 绑定点击事件
    4.2 阻止后续事件执行,e.preventDefault();
    4.3 获取前端参数,3个密码参数
    4.4 验证参数
    4.5 发起ajax请求,朝后端提交数据,url必填,
    4.6 修改成功后,刷新页面location.reload()
    

修改密码后端

后端逻辑

# 只需要功能,不需要页面了,不用render
1.定义返回给前端的数据格式
2.接收参数
3.验证参数
4.正常逻辑
    4.1 修改密码必须登录之后,认证登录装饰器
    4.2 原始密码加密
    4.3 根据用户名(登录后在session中保存的)和密码查询用户是否存在
    4.4 没有查到返回信息
    4.5 新密码加密
    4.6 修改数据表中的新密码,根据pk(登录后在session中保存的id)筛选update(password=加密后的新密码)
    4.7 返回信息

认证登录的装饰器

def login_auth(func):
    """认证登录的装饰器"""

    def inner(request, *args, **kwargs):
        if request.session.get('username'):  # 用户存在,执行正常函数,用户不存在,调登录路由
            return func(request, *args, **kwargs)
        else:
            return redirect('/login/')

    return inner

后端代码

@login_auth
def set_password(request):
    """修改密码"""
    if request.method == 'POST':
        # 1.定义返回前端的数据格式
        back_dic = {'code': 200, 'msg': '修改密码成功'}

        # 2.接收参数
        old_password = request.POST.get('old_password')
        new_password = request.POST.get('new_password')
        re_password = request.POST.get('re_password')

        # 3.验证参数
        if not old_password:
            back_dic['code'] = 1001
            back_dic['msg'] = '原始密码不能为空'
            return JsonResponse(back_dic)
        if not new_password:
            back_dic['code'] = 1002
            back_dic['msg'] = '新密码不能为空'
            return JsonResponse(back_dic)
        if not re_password:
            back_dic['code'] = 1003
            back_dic['msg'] = '确认密码不能为空'
            return JsonResponse(back_dic)

        # 两次密码不一致
        if new_password != re_password:
            back_dic['code'] = 1003
            back_dic['msg'] = '两次密码不一致'
            return JsonResponse(back_dic)

        # 4.正常逻辑
        # 4.1 验证原始密码是正确
        old_pwd = get_md5_pwd(old_password)
        # 4.2 使用用户名和原始密码查询用户对象
        is_right = models.UserInfo.objects.filter(username=request.session.get('username'), password=old_pwd).first()
        print(is_right)
        if not is_right:  # 用户不存在
            back_dic['code'] = 1009
            back_dic['msg'] = '原始密码不正确'
            return JsonResponse(back_dic)
        # 4.3 修改新密码
        new_pwd = get_md5_pwd(new_password)
        # 4.4 入库
        models.UserInfo.objects.filter(pk=request.session.get('id')).update(password=new_pwd)
        return JsonResponse(back_dic)

退出登录

后端逻辑

1.清空session,用flush(),数据库和cookie都删
2.跳转到登录页面redirect('登录页面')

后端代码

def logout(request):
    """退出登录"""
    # 清空session
    request.session.flush()
    # 前端使用的是ajax提交的,后端不能在跳转了,需要自己在前端写路由地址
    return redirect('/login/')

后台数据模拟

用后台管理系统(admin路由)模拟数据。

1.注册表,把自己创建的所有表都注册到后台
在admin.py文件:

from django.contrib import admin

# Register your models here.

from app01 import models
# 想要在后台管理系统中显示表,需要在admin.py中注册表
# 只要注册了,admin就会自动生产针对该注册表的增删改查至少四个功能
admin.site.register(models.UserInfo)
admin.site.register(models.Blog)
admin.site.register(models.Tag)
admin.site.register(models.Category)
admin.site.register(models.Article)
admin.site.register(models.Article2Tag)
admin.site.register(models.UpAndDown)
admin.site.register(models.Comment)

2.修改admin后台管理的表名

class Meta:  # 元信息
    verbose_name_plural = '用户表'  

    # verbose_name = '用户表'    # 会显示:用户表s
    # 英文表名后台自动加个s

3.字段显示中文,给字段增加verbose_name属性

verbose_name='手机号'

4.添加数据,右上角的add

5.添加的外键显示对象,怎么显示相应name呢?

def __str__(self):
    return self.site_name
  1. 数据可以为空,字段加个属性blank=True
null=True, 代表的是数据库中可以为空
blank=True,代表的是django的后台页面上可以为空   

以上操作都跟数据库没有关系,不需要执行数据库迁移命令。
注意事项:绑定时,一定注意用户要对应,不要绑错了

# 复制整篇文章的html代码
点击id='cnblogs_post_body',右击copy,选择Copy outerHTML

总结点

总结button

button在form表单自带提交事件,ajax绑定点击事件后,点击提交就会产生二次提交,怎么改正?

  • 方式一:取消form表单,只显示输入框
  • 方式二:button按钮框写在form表单外面,就没有自动提交事件了
  • 方式三:仍然form中写button,在js中绑定点击事件后,写阻止后续事件的执行,用
e.preventDefault();
或者
return false;

阻止后续事件

如果前端使用的是ajax提交,后端就不能跳转了

因为ajax前端只要后端的结果,如果后端使用redirect('一个页面'),会返回给前端res一整个heml页面,不会跳转的。
为什么退出登录可以跳转,因为退出登录的前端是a链接,是个get请求,就可以直接重定向了

测试阶段的小技巧

登录页面验证码不用自己写,直接使用后端打印出来的,项目上线一定要把所有的print删掉或者注释掉。

也可以给判断加个接口

if request.session.get('code').lower() != code.lower() or True:

这样每次后端都不验证了,但一定是先测试这个条件正确再加,上线之前必须删除。

标签:登录,request,博客,密码,首页,password,BBS,路由
From: https://www.cnblogs.com/zjyao/p/17400231.html

相关文章

  • 原型设计工具个人博客
    以下内容将介绍对比介绍墨刀,Axure,Figma三种原型设计工具的特点和使用方法,并利用墨刀对团队项目进行原型设计。一、墨刀墨刀是一款在线原型设计与协同工具,借助墨刀,产品经理、设计师、开发、销售、运营及创业者等用户群体,能够搭建为产品原型,演示项目效果。墨刀同时也是协作平台,项......
  • BBS-登录功能
    目录一、添加路由1、登陆路由2、生成随机验证码路由二、登录功能前端模板登录前端步骤登录前端代码重点:点击图片自动更新三、添加视图函数后端步骤后端代码1、添加视图函数login2、随机验证码重点功能:随机验证码点击图片换一张验证码后端要先判断验证码的是否正确一、添加......
  • BBS-注册功能
    目录一、添加路由二、注册功能前端模板前端步骤:前端代码前端重点操作注册功能图片实时展示注册功能ajax提交数据三、添加视图函数后端步骤后端代码重点功能:上传图片头像图片实时展示ajax方式提交给后端数据一、添加路由在路由urls.py中要先导入视图层和一些用到的模块fr......
  • 每日总结博客
    1.无人机的硬件:•动力系统•螺旋桨•有刷电机•无刷电机•电调(esc,ElectronicSpeedController)•电池旋翼无人机硬件架构—飞控系统•飞控系统•传感器•加速度计,三轴,测量机体坐标系下的线加速度•角速度计,三轴,测量机体坐标系下的角速度•磁力计,三轴,测量......
  • BBS数据库表结构设计
    目录一、用户表:UserInfo二、博客表:Blog三、文章表:Article四、标签表:Tag五、分类表:Category六、点赞点踩表:UpAndDown七、评论表:Comment八、文章标签表:Tag2Article表结构生成(模型类)九、数据库配置以及数据库迁移十、表关系图片在我们分析完一个项目的需求之后,我们着手开发项目......
  • BBS-个人博客项目
    目录项目开发流程BBS数据库表结构设计项目开发流程1.需求分析2.架构设计3.分组开发4.提交测试5.交付上线#需求分析 功能:支持不同的用户去编写博客,查看,编辑 核心:文章的增删改查#架构设计 表结构,表关系设计。先确定表的数量,再确定表的基础字段,最后确定表的外键......
  • BBS数据库表结构设计
    目录一、用户表:UserInfo二、博客表:Blog三、文章表:Article四、标签表:Tag五、分类表:Category六、点赞点踩表:UpAndDown七、评论表:Comment八、文章标签表:Tag2Article表结构生成(模型类)九、数据库配置以及数据库迁移十、表关系图片在我们分析完一个项目的需求之后,我们着手开发项目......
  • 博客园博客搬家升级后只能搬家一次了
    原来博客园中博客后台中,随笔下的博客搬家功能,可以在晚上下班后,或者周末、节假日等时间段,同步其它博客的文章,功能挺好用。但最近博客同步功能做了限制,提示“每个来源可以且尽可以搬家一次”!存在的搬家记录貌似也不能删除,所以后续其它博客文章将无法定期同步过来了。就这样吧,如果......
  • 第二次博客:PTA题目集4-5总结
    第二次博客:PTA题目集4-5总结 前言:有了前三次的菜单系列的洗礼,我对这两次的点菜还是有一定的信心的。老师也说期中考试会于点菜系列有一定的联系。但是事实告诉你永远不要试图揣测蔡老师的心思。先说期中考试:题目概述:总共4题,(和点菜没有半毛钱关系)不过总体来说......
  • 使用Hexo在Github Pages上部署静态博客
    使用Hexo在GithubPages上部署静态博客写在前面本文写于2023/3/23,具体配置步骤具有时效性,后续如有必要会持续更新。阅读本教程需要有Git和Github基础,对Markdown语法有一定的了解。什么是GithubPages?GitHubPages是一项静态站点托管服务,它直接从GitHub上的仓库获取......