Day22 博客园的构建

整体结构梳理:

知识点:
    
    1、文件上传: 
    
          form表单 
           ajax(formData)
          
          
    2 博客系统注册页面的头像上传
          media路径配置
          
          avatar = models.FileField( upload_to='avatarDir/', default="avatar/default.png")
      
          配置:MEDIA_ROOT=os.path.join(BASE_DIR,"blog","media")
          
                 MEDIA_ROOT+avatarDir/+a.png
             
          配置:
               MEDIA_URL="/media/"
               url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),               
          
          <img src='/media/avatarDir/a.png'>


    3、 博客系统之系统首页的文章渲染
    
    4、  个人站点完成文章归档(分类归档,标签归档,日期归档) (**********)
         跳转---url
         
    5、文章详细页:实现了点赞功能:不能重复点赞;事务     (**********) 

 

上传的功能怎么实现:

前面注册页面:

<body>

<div class="container">

    <div class="row">
        <form class="col-md-6 col-md-offset-2">
              {% csrf_token %}
              <div class="form-group">
                <label for="user">用户名</label>
                {{ regForm.username }} <span class="error"></span>
              </div>
              <div class="form-group">
                <label for="pwd">密码</label>
                {{ regForm.password }} <span class="error"></span>
              </div>
                <div class="form-group">
                <label for="pwd">确认密码</label>
               {{ regForm.repeat_password }} <span class="error"></span>
              </div>
              <div class="form-group">
                <label for="pwd">邮箱</label>
               {{ regForm.email }} <span class="error"></span>
              </div>

                <div class="form-group" id="avatar">
                    <label for="pwd">头像</label>
                    <p><img src="/static/img/default.png" alt="" id="avatar_img"></p>
                     <p><input type="file" id="file"></p>
               </div>



              <div class="row">
                  <div class="col-md-6">
                      <input type="button"value="注册提交" class="btn btn-primary regBtn"><span class="error"></span>
                  </div>
              </div>
        </form>
    </div>

</div>


<script>
     $(".regBtn").click(function () {
         var formdata=new FormData();

         formdata.append("username",$("#id_username").val());
         formdata.append("password",$("#id_password").val());
         formdata.append("repeat_password",$("#id_repeat_password").val());
         formdata.append("email",$("#id_email").val());
         formdata.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val());
         formdata.append("avatar",$("#file")[0].files[0]);


         $.ajax({
             url:"/reg/",
             type:"post",
             data:formdata,
             contentType:false,
             processData:false,
             success:function (data) {
                 var data=JSON.parse(data);
                 //console.log(data);

                 if(data.user){
                     location.href="/login/"
                 }
                 else {
                     var error_dict=data.error_msg ;    //  {"username":["asda"],"email":["asdsa"]}

                     $(".error").html("");
                     $.each(error_dict,function (i,j) {
                         console.log(i,j);
                         $("#id_"+i).next().addClass("pull-right").html(j[0]).css("color","red")

                         if(i=="__all__"){
                             $("#id_repeat_password").next().html(j[0])
                         }
                     })

                 }
             }

         })

     })


    // 预览功能

    $("#file").change(function () {

          var choose_file=$("#file")[0].files[0];

          var reader=new FileReader();

         reader.readAsDataURL(choose_file);

         reader.onload=function () {
            $("#avatar_img").attr("src",this.result)
        }




    })

</script>
后台views怎么写的:

def reg(request):

    if request.is_ajax():
        regForm=RegForm(request.POST)

        regResponse={"user":None,"error_msg":None}
        if regForm.is_valid():
            username=regForm.cleaned_data.get("username")
            password=regForm.cleaned_data.get("password")
            email=regForm.cleaned_data.get("email")
            avatar=request.FILES.get("avatar")
            print(regForm.cleaned_data,"------")
            user=UserInfo.objects.create_user(username=username,password=password,email=email,avatar=avatar)
            regResponse["user"]=user.username

        else:
            regResponse["error_msg"]=regForm.errors  # errors只存错误字段
        return HttpResponse(json.dumps(regResponse))

    regForm=RegForm()

    return render(request,'reg.html',locals())

个人首页编辑:

这里边最主要的是几个标签分类的做法:

前台页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
     <link rel="stylesheet" href="/static/dist/css/bootstrap.css">
    <script src="/static/dist/js/jquery-3.2.1.js"></script>
    <script src="/static/dist/js/bootstrap.js"></script>
    <link rel="stylesheet" href="/static/css/homeSite.css">
    <link rel="stylesheet" href="/static/css/articleDetail.css">
</head>
<body>
<div class="header">
    <div class="title">{{ username }}的个人博客</div>
</div>

<div class="container">
    <div class="row">
        <div class="col-md-3 left">
                  <div class="panel panel-success">
                      <div class="panel-heading">公告</div>
                      <div class="panel-body">
                        <p>昵称:{{ user.username }}</p>
                        <p>园龄:{{ user.create_time|date:'Y-m-d' }}</p>
                        <p>头像:<img src="/media/{{ user.avatar }}" alt="" width="60" height="60"></p>
                      </div>
                   </div>
                   <div class="panel panel-warning">
                      <div class="panel-heading">分类归档</div>
                      <div class="panel-body">
                        {% for cate in cateList %}
                           <p><a href="/blog/{{ user.username }}/category/{{ cate.title }}">{{ cate.title }}({{ cate.article_set.all.count }})</a></p>
                        {% endfor %}

                      </div>
                   </div>
                   <div class="panel panel-info">
                      <div class="panel-heading">标签归档</div>
                      <div class="panel-body">
                        {% for tag in tagList %}
                        <p><a href="/blog/{{ user.username }}/tag/{{ tag.title }}">{{ tag.title }}({{ tag.article_set.all.count }})</a></p>
                        {% endfor %}

                      </div>
                   </div>

                   <div class="panel panel-danger">
                      <div class="panel-heading">日期归档</div>
                      <div class="panel-body">
                        {% for date in dateList %}
                           <p><a href="/blog/{{ user.username }}/date/{{ date.0 }}">{{ date.0 }}({{ date.1 }})</a></p>
                        {% endfor %}

                      </div>
                   </div>
        </div>
        <div class="col-md-9 right">
               {% block con %}
                 <div class="articleList">
                    {% for article in article_list %}
                     <div class="article_item">
                         <div><a href="/blog/{{ article.user.username }}/articles/{{ article.nid }}">{{ article.title }}</a></div>
                         <div class="text">
                                {{ article.desc }}
                         </div>
                         <div class="icon">
                             <a href="">{{ article.user.username }}</a>
                             <span>&nbsp;&nbsp;发布于&nbsp;&nbsp;{{ article.create_time|date:'Y-m-d H:i' }}</span>&nbsp;&nbsp;
                             <a href=""><span class="glyphicon glyphicon-thumbs-up"></span><span>点赞数({{ article.up_count }})</span></a>&nbsp;&nbsp;
                             <a href=""><span class="glyphicon glyphicon-comment"></span><span>评论数({{ article.comment_count }})</span></a>
                         </div>
                         <hr>
                     </div>
                    {% endfor %}
               </div>
               {% endblock %}
        </div>
    </div>
</div>


</body>
</html>








后端代码:
def homeSite(request,username,**kwargs):
    print(kwargs,"=====")
    # 查询当前的用户对象
    user=UserInfo.objects.get(username=username)
   # 查询当前站点对象
    blog=user.blog


    # 查询当前站点所有的文章
    if not kwargs:
        article_list=Article.objects.filter(user__username=username).order_by("-create_time")
    else:
        if kwargs.get("condition")=="category":
            para=kwargs.get("para")
            print(kwargs)
            article_list=Article.objects.filter(user__username=username).filter(homeCategory__title=para)
        elif kwargs.get("condition")=="tag":pass
        else:pass
    # 查询当前站点的所有分类名称
    #方式1:
    cateList=models.HomeCategory.objects.filter(blog=blog)

    #方式2: 查询每一个分类名称以及对应的文章个数
    from django.db.models import Count,Sum,Min
    # cate_list=models.HomeCategory.objects.filter(blog=blog).annotate(c=Count("article__nid")).values_list("title","c")
    # print(cate_list) # <QuerySet [('yuan的python', 2), ('yuan的数据库', 1)]>


    ########################
    # 查询当前站点所有标签的名称以及对应的文章数
    tagList=models.Tag.objects.filter(blog=blog)

    #
    dateList=models.Article.objects.filter(user=user).extra(select={"formatDate":"strftime('%%Y-%%m',create_time)"}).values_list("formatDate").annotate(Count("nid"))
    # print(dateList)
    return render(request,"homeSite.html",locals())
原文地址:https://www.cnblogs.com/sexiaoshuai/p/8027132.html