整体结构梳理:
知识点: 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> 发布于 {{ article.create_time|date:'Y-m-d H:i' }}</span> <a href=""><span class="glyphicon glyphicon-thumbs-up"></span><span>点赞数({{ article.up_count }})</span></a> <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())