BBS首页搭建(包括修改密码和退出功能实现)+后台管理+media配置,用户头像展示+个人站点文章展示(图片防盗链、左边侧边栏、侧边栏筛选)

1.首页导航条

2.导航条修改密码及注册功能(修改密码,或者退出需要用户登录,需要加上登录装饰器,导入,然后全局配)

3.admin后台管理(首页搭建好了,文章还没录入,有7张表,一张一张录比较麻烦,就借助于后台管理,先创建createsuperuser)

4.media配置以及用户头像展示 

5.个人站点文章展示(图片防盗链,文章展示)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views
from django.views.static import serve
from dj_BBS01 import settings

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r"^register/", views.register, name='reg'),
    url(r"^login/", views.login, name='login'),
    url(r"^get_code/", views.get_code, name='gc'),
    url(r"^home/", views.home, name='hm'),
    # 修改密码
    url(r"^set/password/", views.set_password, name='set_pwd'),
    # 退出
    url(r"^logout/", views.logout, name='logout'),
    #点赞点踩
    url(r"^up_or_down/",views.up_or_down),
    #评论
    url(r"^comment/",views.comment),
    #后台管理
    url(r"^backend/", views.backend),
    #添加文章
    url(r"^add/article/",views.add_article),
    #编辑器上传图片接口
    url(r"^upload/image/",views.upload_image),
   #添加头像
    url(r"^set/avatar/",views.set_avatar),
    # 暴露后端指定文件夹资源
     url(r"^media/(?P<path>.*)", serve, {'document_root': settings.MEDIA_ROOT}),
    # url(r"app01/(?P<path>.*)",serve,{'document_root':settings.MEDIA_ROOT})
    #个人站点页面搭建
    url(r"^(?P<username>\w+)/$",views.site,name="site"),
    #侧边栏筛选功能
    url(r"^(?P<username>\w+)/(?P<condition>category|tag|archive)/(?P<param>.*)/",views.site),
     #文章详情页
    url(r"^(?P<username>\w+)/article/(?P<article_id>\d+)/",views.article_detail),


]

home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
     {% load static %}
    <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>
</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="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li role="separator" class="divider"></li>
            <li><a href="#">Separated link</a></li>
            <li role="separator" class="divider"></li>
            <li><a href="#">One more separated link</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">Submit</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">
            <li><a href="#" data-toggle="modal" data-target="#myModal" >修改密码</a></li>
            <li><a href="/backend/">后台管理</a></li>
            <li><a href="/set/avatar/">修改头像</a></li>
            <li role="separator" class="divider"></li>
            <li><a href="{% url 'logout'%}">退出登录</a></li>
          </ul>




<!-- Modal -->
<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" id="myModalLabel" class="text-center">修改密码</h4>
      </div>
      <div class="modal-body">
         <div class="row">
             <div class="col-md-8 col-md-offset-2">
                 <div class="form-group">
                     <label for="">用户名</label>
                     <input type="text" class="form-control" disabled value="{{ request.user.username }}">
                 </div>
                 <div class="form-group">
                     <label for="">原密码</label>
                     <input type="password" id="id_old_password" class="form-control" name="old_password">
                 </div>
                 <div class="form-group">
                      <label for="">新密码</label>
                     <input type="password" id="id_new_password" class="form-control" name="new_password">
                 </div>
                 <div class="form-group">
                      <label for="">确认密码</label>
                     <input type="password" id="id_confirm_password" class="form-control" name="confirm_password">
                 </div>

             </div>
         </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
        <button type="button" class="btn btn-primary" id="id_edit">保存修改</button>
          <span style="color: red" id="password_error"></span>
      </div>
    </div>
  </div>
</div>






        </li>
             {% else %}
                 <li><a href="{% url 'reg' %}">注册</a></li>
                <li><a href="{% url 'login' %}">登录</a></li>
          {% endif %}



      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>

<div class="container-fluid">
    <div class="col-md-2">
        <div class="panel panel-primary">
  <div class="panel-heading">
    <h3 class="panel-title">灵魂在高处</h3>
  </div>
  <div class="panel-body">
    清晨,如果我比往常早点去公司,总会在一个特定的时间和路段,与一位中年环卫工相遇。
  </div>
</div>
        <div class="panel panel-danger">
  <div class="panel-heading">
    <h3 class="panel-title">人最软弱的地方是舍不得</h3>
  </div>
  <div class="panel-body">
    人最软弱的地方是舍不得 真正的爱情,不是一见钟情,而是日久生情;真正的缘份,不是上天的安排,而是你的主动;真正的自卑
  </div>
</div>
        <div class="panel panel-info">
  <div class="panel-heading">
    <h3 class="panel-title">学会低头,更能出头</h3>
  </div>
  <div class="panel-body">
    低头是一种能力,它不是自卑,也不是怯弱,它是清醒中的嬗变。
学会低头,更能出头有时,稍微低一下头,或许我们的人生路会更精彩。
懂得低头,才能出头!
  </div>
</div>
    </div>
    <div class="col-md-8">
        <ul class="media-list">

           {% for article_obj in article_queryset %}
                <li class="media">
                 <h4 class="media-heading"><a href="/{{ article_obj.blog.userinfo.username }}/article/{{ article_obj.pk }}" >{{ article_obj.title}}</a></h4>
    <div class="media-left">
      <a href="#">
        <img class="media-object" src="/{{ article_obj.blog.userinfo.avatar }}" width=60 alt="...">
      </a>
    </div>
    <div class="media-body">

      {{ article_obj.desc }}
    </div>
                    <br>
                    <div>
                        <span><a href="/{{ article_obj.blog.userinfo.username }}/article/{{ article_obj.pk }}">{{ article_obj.blog.userinfo.username}}&nbsp;&nbsp;</a></span>
                        <span>发布于&nbsp;&nbsp;</span>
                        <span>{{ article_obj.create_time }}&nbsp;&nbsp;</span>
                        <span><span class="glyphicon glyphicon-comment"></span>评论({{ article_obj.comment_num }})&nbsp;&nbsp;</span>
                        <span><span class="glyphicon glyphicon-thumbs-up"></span>点赞({{ article_obj.up_num }})</span>
                    </div>


  </li>
               <hr>

           {% endfor %}

        </ul>
    </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">
    清晨,如果我比往常早点去公司,总会在一个特定的时间和路段,与一位中年环卫工相遇。
  </div>
</div>
        <div class="panel panel-danger">
  <div class="panel-heading">
    <h3 class="panel-title">人最软弱的地方是舍不得</h3>
  </div>
  <div class="panel-body">
    人最软弱的地方是舍不得 真正的爱情,不是一见钟情,而是日久生情;真正的缘份,不是上天的安排,而是你的主动;真正的自卑
  </div>
</div>
        <div class="panel panel-info">
  <div class="panel-heading">
    <h3 class="panel-title">学会低头,更能出头</h3>
  </div>
  <div class="panel-body">
    低头是一种能力,它不是自卑,也不是怯弱,它是清醒中的嬗变。
学会低头,更能出头有时,稍微低一下头,或许我们的人生路会更精彩。
懂得低头,才能出头!
  </div>
</div>
    </div>
</div>




<script>
    $("#id_edit").click(function(){
        $.ajax({
            url:'/set_password/',
            type:'post',
            data:{
                "old_password":$("#id_old_password").val(),
                "new_password":$("#id_new_password").val(),
                "confirm_password":$("#id_confirm_password").val(),
                "csrfmiddlewaretoken":'{{ csrf_token }}'
            },
            success:function (args) {
               if (args.code==1000){
                   {#window.location.href='home/'#}
                   window.location.reload()
                   {#$('#myModal').modal('hide')#}
               }else{

                   $("#password_error").text(args.msg)

               }
            }
        })
    })
</script>
</body>
</html>

views.py

from django.contrib.auth.decorators import login_required

@login_required  # 必须先登录才能修改密码
def set_password(request):
    if request.is_ajax():
        back_dic = {"code": 1000, 'msg': ""}
        if request.method == "POST":
            old_password = request.POST.get('old_password')
            new_password = request.POST.get('new_password')
            confirm_password = request.POST.get('confirm_password')
            is_right = request.user.check_password(old_password)
            if is_right:
                if new_password == confirm_password:
                    request.user.set_password(new_password)
                    request.user.save()
                    back_dic['msg'] = '修改成功'
                else:
                    back_dic['code'] = 1001
                    back_dic['msg'] = '两次密码并不一致'
            else:
                back_dic['code'] = 1002
                back_dic['msg'] = '原密码错误'
        return JsonResponse(back_dic)


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

settings.py

LOGIN_URL='/login/'

 media配置(复制媒体对象)

用户头像展示

 

 

#settings.py配置用户上传的文件存储位置
MEDIA_ROOT=os.path.join(BASE_DIR,"media")
# MEDIA_ROOT=os. path.join(BASE_DIR,"app01")

个人站点展示(图片防盗链)

 

 views.py

def site(request,username,**kwargs):
    """
    如果该参数有值,也就意味着需要对article_list做额外的判断
    :param request:
    :param username:
    :param kwargs:
    :return:
    """
    #先校验当前用户名对应的个人站点是否存在

    user_obj=models.UserInfo.objects.filter(username=username).first()
   #用户如果不存在返回一个404页面
    if not user_obj:
        return render(request,'error.html')
    blog=user_obj.blog   #存在则返回个人站点页面,先拿到个人站点
    #查看当前个人站点的所有文章
    article_list=models.Article.objects.filter(blog=blog)
    if kwargs:
        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("-")
            article_list=article_list.filter(create_time__year=year,create_time__month=month)

    #查寻当前站点下所有的分类以及分类下的文章数
    category_list=models.Category.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list('name','count_num','pk')
    #print(category_list)
    #查寻当前站点下所有的标签以及标签下的文章数
    tag_list=models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list("name",'count_num','pk')
    #print(tag_list)
    #查寻当前站点下所有的时间分类以及文章数
    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 render(request,'site.html',locals())

 error.html(直接复制博客园页面的404)

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <link rel="icon" href="//common.cnblogs.com/favicon.ico" type="image/x-icon" />
    <title>404 页面不存在 - 博客园</title>
    <style type='text/css'>
        body {
            margin: 8% auto 0;
            max-width: 400px;
            min-height: 200px;
            padding: 10px;
            font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
            font-size: 14px;
            padding-right: 200px;
            position: relative;
        }
        p { color: #555;margin: 15px 0px; }
        img { border: 0px; }
        .d { color: #404040; }
        .robot img { max-width: 192px; }
        .robot { position: absolute; top: 0; right: 0; }
    </style>
</head>
<body>
    <p style="margin-left: 5px;"><a href="https://www.cnblogs.com/"><img src="//common.cnblogs.com/logo.svg" style="height:45px" alt="cnblogs"></a></p>
    <div style="margin-top:20px">
        <p style=""><b style="">404.</b> 抱歉,您访问的资源不存在。</p>
        <p class="d">可能是网址有误,或者对应的内容被删除,或者处于私有状态。</p>
        <p style="color:#777;">代码改变世界,联系邮箱 contact@cnblogs.com</p>
    </div>
    <div class="robot"><a href="//www.cnblogs.com/cmt/articles/13940458.html"><img src="//common.cnblogs.com/images/404-robot.png" alt="404 robot" /></a></div>
    <script async src="https://www.googletagmanager.com/gtag/js?id=G-4CQQXWHK3C"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());

      gtag('config', 'G-4CQQXWHK3C');
    </script>
</body>
</html>

site.html

{% extends 'base.html' %}

{% block content %}

        <div class="col-md-9">
            <ul class="media-list">

           {% for article_obj in article_list %}
                <li class="media">
                 <h4 class="media-heading"><a href="/{{ username }}/article/{{ article_obj.pk }}" >{{ article_obj.title}}</a></h4>
    <div class="media-left">
      <a href="#">
        <img class="media-object" src="/{{ article_obj.blog.userinfo.avatar }}" width=60 alt="...">
      </a>
    </div>
    <div class="media-body">

      {{ article_obj.desc }}
    </div>


                    <div class="pull-right">
                        <span>posted&nbsp;&nbsp;</span>
                        <span>@&nbsp;&nbsp;</span>
                        <span>{{ article_obj.create_time|date:'Y-m-d' }}&nbsp;&nbsp;</span>
                        <span><a href="">{{ article_obj.blog.userinfo.username}}&nbsp;&nbsp;</a></span>
                        <span><span class="glyphicon glyphicon-comment"></span>评论({{ article_obj.comment_num }})&nbsp;&nbsp;</span>
                        <span><span class="glyphicon glyphicon-thumbs-up"></span>点赞({{ article_obj.up_num }})&nbsp;&nbsp;</span>
                        <span><a href="">编辑</a></span>
                    </div>


  </li>
               <hr>

           {% endfor %}

        </ul>
        </div>
{% endblock %}

 

 

 

 

posted @ 2022-02-26 19:41  甜甜de微笑  阅读(178)  评论(0编辑  收藏  举报