BBS仿博客园代码总结2---首页导航条搭建、改密码、注销登录、admin后台管理、后台数据绑定、主页面文章内容区页面搭建、media媒体目录

首页导航条相关代码

整体思路就是先把主页的导航条搭好,利用模态框作为修改密码的的页面,
提交修改密码数据的按钮弄一个点击事件,获取模态框里面的老密码,新密码,确认密码,利用ajax将数据发给后端的该密码视图函数
if request.user.check_password(old_pwd):
    # 再校验两次密码是否一致,以及两次密码不能为空
    if new_pwd == confirm_pwd and new_pwd:
        request.user.set_password(new_pwd)  # 修改密码
        request.user.save()  # 保存密码
------------------------------
然后把小逻辑补一下,修改密码视图函数就结束了
------------------------------
auth.logout(request)
return redirect('/home/')

# 注销登录就两行代码
------------------------------

.
.

    # 网站首页
    path('home/', views.home_func, name='home_view'),

---------------------------------------------
def home_func(request):
    # 查询所有用户编写的文章
    article_queryset = models.Article.objects.all()
    # 分页器
    from app01 import mypage
    page_obj = mypage.Pagination(current_page=request.GET.get('page'), all_count=article_queryset.count())
    part_queryset = article_queryset[page_obj.start:page_obj.end]
    return render(request, 'homePage.html', locals())
---------------------------------------------

.
.

home页面的html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/static/jQuery3.6.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.4.1-dist/css/bootstrap.min.css">
    <script src='/static/bootstrap-3.4.1-dist/js/bootstrap.min.js'></script>
</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>
            </ul>

            <form class="navbar-form navbar-left">
                <div class="form-group">
                    <input type="text" class="form-control" placeholder="搜索">
                </div>
                <button type="submit" class="btn btn-default">搜索</button>
            </form>

            <ul class="nav navbar-nav navbar-right">
                <!--判断是匿名用户还是已登录用户-->
                {% if request.user.is_authenticated %}
                    <li><a href="#">{{ request.user.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">
                            <!--data-toggle与data-target是用来触发模态框弹出的 -->
                            <li><a href="#" data-toggle="modal" data-target="#myModal">修改密码</a></li>
                            <li><a href="#">修改头像</a></li>
                            <li><a href="#">后台管理</a></li>
                            <li role="separator" class="divider"></li>
                            <li><a href="/app01/logout/">注销登录</a></li>
                        </ul>
                    </li>
                {% else %}
                    <li><a href="{% url 'register_view' %}">注册</a></li>
                    <li><a href="{% url 'login_view' %}">登录</a></li>
                {% endif %}

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


<!--模态框开始-->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
                </button>

                <h4 class="modal-title text-center" id="myModalLabel">修改密码</h4>
            </div>
            <div class="modal-body">

                <!--这块自己写的!!!-->
                <div class="form-group">
                    <label for="">用户名</label>
                    <input type="text" value="{{ request.user.username }}" disabled class="form-control">
                </div>
                <div class="form-group">
                    <label for="">原密码</label>
                    <input type="text" id="old_pwd" class="form-control">
                </div>
                <div class="form-group">
                    <label for="">新密码</label>
                    <input type="text" id="new_pwd" class="form-control">
                </div>
                <div class="form-group">
                    <label for="">确认密码</label>
                    <input type="text" id="confirm_pwd" class="form-control">
                </div>
            </div>
            <div class="modal-footer">
                <span id="error" style="color: red"></span>

                <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                <button type="button" class="btn btn-warning" id="setBtn">修改</button>
            </div>
        </div>
    </div>
</div>
<!--模态框结束-->




<script>
    $('#setBtn').click(function () {
        $.ajax({
            url: '/app01/set_pwd/',
            type: 'post',
            data: {
                'old_pwd': $('#old_pwd').val(),
                'new_pwd': $('#new_pwd').val(),
                'confirm_pwd': $('#confirm_pwd').val(),
                'csrfmiddlewaretoken': '{{csrf_token}}'
            },

            success:function (args) {
                if (args.code === 10000){
                    window.location.href = args.url
                }else{
                    $('#error').text(args.msg)
                }
            }

        })
    })
</script>
<!--用jquery拿用户输在标签里面的数据时,不需要像form表单一样,要input标签具有name属性才能在后端通过request.POST.get('')拿用户写在标签里面的数据-->
</body>
</html>
---------------------------------------------

.
.
.

改密码与注销登录

   # 修改密码
    path('set_pwd/', views.set_pwd_func),

    # 注销登录
    path('logout/', views.logout_func),
---------------------------------------------
# 在settings配置文件里面配一个LOGIN_URL = '/login/'

@login_required
def set_pwd_func(request):
    back_dict = {'code': 10000, 'msg': ''}
    if request.method == 'POST':
        old_pwd = request.POST.get('old_pwd')
        new_pwd = request.POST.get('new_pwd')
        confirm_pwd = request.POST.get('confirm_pwd')
        # 校验原密码是否正确
        if request.user.check_password(old_pwd):
            # 校验两次密码是否一致,以及两次密码不能为空
            if new_pwd == confirm_pwd and new_pwd:
                # 修改密码
                request.user.set_password(new_pwd)
                request.user.save()
                back_dict['msg'] = '密码修改成功'
                back_dict['url'] = '/app01/login/'
                # auth组件会自动在你密码修改成功后,将原来登录成功的状态给注销掉
            else:
                back_dict['code'] = '10001'
                back_dict['msg'] = '两次密码不一致或者密码为空'
        else:
            back_dict['code'] = '10002'
            back_dict['msg'] = '原密码输入不正确'
        return JsonResponse(back_dict)
-------------------------------------------

@login_required
def logout_func(request):
    auth.logout(request)
    return redirect('/home/')

.
.

admin后台管理

tools里面run manage.py task 在快捷命令行里面,创建超级管理员用户,进入django提供的admin后台管理里面。

要在admin.py文件里面,把想要操作的模型表在该文件里面注册一下

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

.
.

后台数据绑定

后台数据的绑定,注意用户信息表与个人站点表的绑定一定不要绑错了,因为后面我们要通过个人站点查该用户的文章,个人咱店绑错了,就会导致该个人站点下显示的都是别人的文章了,文章与个人站点表有外键联系,但是与个人信息表没有外键联系!!!

从文章表开始入手,创建站点表,标签表,分类表,文章与标签多对多的表,的表数据
点赞点踩表与评论表可以暂时不用绑数据

.
.
.

主页面文章内容区页面搭建

<!--内容区开始-->
<div class="container-fluid">
    <div class="row">
        <!--左广告栏-->
        <div class="col-md-2">
              <div class="panel panel-primary">
                  <div class="panel-heading">
                    <h3 class="panel-title">重金求子</h3>
                  </div>
                  <div class="panel-body">
                    事后必有重谢:wuyong123
                  </div>
              </div>
        </div>

        <!--内容区-->
        <div class="col-md-8">
            <div class="text-center">{{ page_obj.page_html|safe }}</div>

            {% for article_obj in part_queryset %}
                <!--bootstrap媒体对象里面拿的样式代码-->
                <div class="media">
                      <h4 class="media-heading"><a href="#">{{ article_obj.title }}</a></h4>  <!--文章标题-->
                      <div class="media-left">
                        <a href="#">
                            <!--文章对象跨表查询拿到用户信息表里面的头像-->
                            <!--注意如果有路由分发,前面的路径要拼全了,漏忘了app01 ,发送请求的网站就变成了http://127.0.0.1:8099/media/avatar/3333.jpg/-->
                          <img class="media-object" src="/app01/media/{{ article_obj.site.userinfo.avatar }}/" alt="..." width="80">
                        </a>
                      </div>
                      <div class="media-body">

                        {{ article_obj.desc }}
                          <!--文章简介-->
                      </div>
                    <br>

       <!--br有换行的作用,和上面标签就隔开一点了-->
       <!--文章对应的用户名,时间,点赞数,点踩数,评论数-->
       <!--文章对象拿用户名,先通过外键正向到个人站点表,再反向表名小写到个人信息表-->
       <!--由于个人站点与个人信息是一对一的所以表名小写后面不要加_set-->

                <div>
                  <span><a href="/{{ article_obj.site.userinfo.username }}/">{{ article_obj.site.userinfo.username }}</a></span>

                  <span style="margin-right: 20px">{{
article_obj.create_time|date:'Y-m-d H:i' }}</span>

                  <span class="glyphicon glyphicon-thumbs-up"
style="margin-right: 20px">{{ article_obj.up_num }}</span>

                  <span class="glyphicon glyphicon-thumbs-down"
style="margin-right: 20px">{{ article_obj.down_num }}</span>

                  <span class="glyphicon glyphicon-comment"
style="margin-right: 20px">{{ article_obj.comment_num }}</span>

                </div>
         </div>
                <hr>    <!--分割线-->
            {% endfor %}

            <!--分页器标签 page_html就是分页器类里面专门用来控制分页器标签数量与样式的函数-->
            <!--注意对象别用错了,要用分页器类产生的对象去点page_html,千万别误用成for循环出来的对象-->
            <div class="text-center">{{ page_obj.page_html|safe }}</div>
        </div>

        <!--右广告栏-->
        <div class="col-md-2">
            <div class="panel panel-primary">
                  <div class="panel-heading">
                    <h3 class="panel-title">重金求子</h3>
                  </div>
                  <div class="panel-body">
                    事后必有重谢:wuyong123
                  </div>
            </div>
        </div>


    </div>
</div>
<!--内容区结束-->

.
.
.

media媒体目录

想做意见事情,用户无论上传什么东西,都固定的存到某一个目录下,在该目录下再去划分,上传的东西属于什么类型的。

需要在settings 文件里面加一句话
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

以后用户上传的静态文件会自动存到media文件目录下,但是针对用户上传的文件,我们在模型层又限制了字段数据要存到固定的比如头像字段数据存avatar目录下
那么就会变成自动在media目录下再开一个avatar目录存用户上传的头像字段数据,其他的字段的数据要存的目录也同理开在media目录下

这样以后media目录下面存储的所有用户上传的媒体文件,为什么不直接存数据库里面的表里面,因为文件类型的数据,在数据库里面都是存储的文件路径,不存文件的整体的

最后 还要到路由层写自定义暴露资源接口
# 写暴露资源接口用
from django.views.static import serve
from django.conf import settings
re_path('media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})

这样弄好后,media目录下所有的资源就都暴露出来了,只要在浏览器里面,路由先写media,后面只要路径写对了,就能访问到后端media目录下对应路径的文件资源了!!!



该方法可以支持暴露任何你想要暴露的后端文件数据,只要settings里面目录名一改,路由层的开头的路由名一改就行了,打个比方都换成app01,这样在浏览器就可以访问后端app01下面所有的文件了!!!

.
.
image
.
因为我们并没有开设avatar目录的访问权限
image
.
image
.
.
.

posted @   tengyifan  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示