一、路由
from django. contrib import admin
from django. urls import path, re_path
from app01 import views
from django. views. static import serve
from django. conf import settingsurlpatterns = [ path( 'admin/' , admin. site. urls) , path( 'register/' , views. register) , path( 'login/' , views. login) , path( 'get_code/' , views. get_code) , path( 'home/' , views. home) , path( 'logout/' , views. logout) , path( 'set_password/' , views. set_password) , re_path( 'media/(?P<path>.*)' , serve, { 'document_root' : settings. MEDIA_ROOT} ) , re_path( '(?P<username>\w+)/(?P<article_id>\d+)' , views. article_detail) , path( 'up_and_down/' , views. up_and_down) , path( 'comment/' , views. comment) , re_path( '(?P<username>\w+)/(?P<condition>category|tag|archive)/(?P<param>.*)' , views. site) , re_path( '(?P<username>\w+)' , views. site) ,
]
二、文章详情页
1.前端
{% extends 'home.html' %}{% block css %}< style> .s1 { margin-right : 10px; color : #999; } .content { font-size : 18px; color : #444; } #div_digg { float : right; margin-bottom : 10px; margin-right : 30px; font-size : 12px; width : 128px; text-align : center; margin-top : 10px; } .diggit { float : left; width : 46px; height : 52px; background : url ( /static/img/upup.gif) no-repeat; text-align : center; cursor : pointer; margin-top : 2px; padding-top : 5px; } .buryit { float : right; margin-left : 20px; width : 46px; height : 52px; background : url ( /static/img/downdown.gif) no-repeat; text-align : center; cursor : pointer; margin-top : 2px; padding-top : 5px; } .clear { clear : both; } .diggword { margin-top : 5px; margin-left : 0; font-size : 12px; color : #808080; } .clearfix:focus { content : '' ; display : block; clear : both; } </ style>
{% endblock %}{% block content %}< div class = " col-md-3" > < div class = " panel panel-info" > < div class = " panel-heading" > 文章分类</ div> < div class = " panel-body" > {% for category in category_list %}< p> < a href = " /{{ username }}/category/{{ category.2 }}" > {{ category.0 }} ({{ category.1 }})</ a> </ p> {# < p> < a href = " /{{ username }}/category/{{ category.pk }}" > {{ category.name }} ({{ category.count_article_num }})</ a> </ p> #}{% endfor %}</ div> </ div> < div class = " panel panel-success" > < div class = " panel-heading" > 文章标签</ div> < div class = " panel-body" > {% for tag in tag_list %}< p> < a href = " /{{ username }}/tag/{{ tag.2 }}" > {{ tag.0 }} ({{ tag.1 }})</ a> </ p> {% endfor %}</ div> </ div> < div class = " panel panel-danger" > < div class = " panel-heading" > 日期归档</ div> < div class = " panel-body" > {% for date in date_list %}{# < p> < a href = " " > {{ date.0 }} ({{ date.1 }})</ a> </ p> #}< p> < a href = " /{{ username }}/archive/{{ date.month|date:'Y-m' }}" > {{ date.month|date:'Y年m月' }}({{ date.count_article_nums }})</ a> </ p> {% endfor %}</ div> </ div> </ div> < div class = " col-md-9" > < h3 style = " color : #399ab2; " > {{ article_detail.title }}</ h3> < div class = " content" > {{ article_detail.content|safe }}</ div> </ div> {% endblock %}{% block js %}< script> { % comment % } function votePost ( id, flag ) { is_up = flag === 'Digg' ? 0 : 1 ; } { % endcomment % } $ ( ".active" ) . click ( function ( ) { let is_up = $ ( this ) . hasClass ( 'diggit' ) ; var article_id = '{{ article_detail.pk }}' ; var _this = $ ( this ) ; $. ajax ( { url : '/up_and_down/' , type : 'post' , data : { is_up : is_up, article_id : article_id, csrfmiddlewaretoken : '{{ csrf_token }}' } , success : function ( ) { if ( res === 200 ) { $ ( "#digg_tips" ) . text ( res. msg) ; let old_num = _this. children ( ) . text ( ) ; { #_this. children ( ) . text ( parseInt ( old_num) + 1 ) ; #} _this. children ( ) . text ( Number ( old_num) + 1 ) ; } else { $ ( "#digg_tips" ) . html ( res. msg) ; } } , } ) ; } ) ; </ script>
{% endblock %}
2.后端
def article_detail ( request, username, article_id) : print ( article_id) user_obj = models. UserInfo. objects. filter ( username= username) . first( ) print ( user_obj) if not user_obj: '''图片防盗链:通过 Referer参数判断,通过这个参数就可以知道你当前的地址是从哪个网页调过来的,然后做验证 ''' return render( request, '404.html' ) blog = user_obj. blogarticle_detail = models. Article. objects. filter ( pk= article_id) . first( ) category_list = models. Category. objects. filter ( blog= blog) . annotate( count_article_num= Count( 'article__pk' ) ) . values_list( 'name' , 'count_article_num' , 'pk' ) tag_list = models. Tag. objects. filter ( blog= blog) . annotate( count_article_num= Count( 'article__pk' ) ) . values_list( 'name' , 'count_article_num' , 'pk' ) date_list = models. Article. objects. annotate( month= TruncMonth( 'create_time' ) ) . values( 'month' ) . filter ( blog= blog) . annotate( count_article_nums= Count( 'pk' ) ) . values( 'month' , 'count_article_nums' ) comment_list = models. Comment. objects. filter ( article_id= article_id) . all ( ) return render( request, 'article_detail.html' , locals ( ) )
三、点赞点菜
1.前端
{% extends 'home.html' %}{% block css %}< style> .s1 { margin-right : 10px; color : #999; } .content { font-size : 18px; color : #444; } #div_digg { float : right; margin-bottom : 10px; margin-right : 30px; font-size : 12px; width : 128px; text-align : center; margin-top : 10px; } .diggit { float : left; width : 46px; height : 52px; background : url ( /static/img/upup.gif) no-repeat; text-align : center; cursor : pointer; margin-top : 2px; padding-top : 5px; } .buryit { float : right; margin-left : 20px; width : 46px; height : 52px; background : url ( /static/img/downdown.gif) no-repeat; text-align : center; cursor : pointer; margin-top : 2px; padding-top : 5px; } .clear { clear : both; } .diggword { margin-top : 5px; margin-left : 0; font-size : 12px; color : #808080; } .clearfix:focus { content : '' ; display : block; clear : both; } </ style>
{% endblock %}{% block content %}< div class = " col-md-3" > < div class = " panel panel-info" > < div class = " panel-heading" > 文章分类</ div> < div class = " panel-body" > {% for category in category_list %}< p> < a href = " /{{ username }}/category/{{ category.2 }}" > {{ category.0 }} ({{ category.1 }})</ a> </ p> {# < p> < a href = " /{{ username }}/category/{{ category.pk }}" > {{ category.name }} ({{ category.count_article_num }})</ a> </ p> #}{% endfor %}</ div> </ div> < div class = " panel panel-success" > < div class = " panel-heading" > 文章标签</ div> < div class = " panel-body" > {% for tag in tag_list %}< p> < a href = " /{{ username }}/tag/{{ tag.2 }}" > {{ tag.0 }} ({{ tag.1 }})</ a> </ p> {% endfor %}</ div> </ div> < div class = " panel panel-danger" > < div class = " panel-heading" > 日期归档</ div> < div class = " panel-body" > {% for date in date_list %}{# < p> < a href = " " > {{ date.0 }} ({{ date.1 }})</ a> </ p> #}< p> < a href = " /{{ username }}/archive/{{ date.month|date:'Y-m' }}" > {{ date.month|date:'Y年m月' }}({{ date.count_article_nums }})</ a> </ p> {% endfor %}</ div> </ div> </ div> < div class = " col-md-9" > < h3 style = " color : #399ab2; " > {{ article_detail.title }}</ h3> < div class = " content" > {{ article_detail.content|safe }}</ div> < div class = " clearfix" > < div id = " div_digg" > < div class = " diggit active" onclick = " votePost ( 11647089 , 'Digg' ) " > < span class = " diggnum" id = " digg_count" > {{ article_detail.up_num }}</ span> </ div> < div class = " buryit active" onclick = " votePost ( 11647089 , 'Bury' ) " > < span class = " burynum" id = " bury_count" > {{ article_detail.down_num }}</ span> </ div> < div class = " clear" > </ div> < div class = " diggword" id = " digg_tips" style = " color : red; " > </ div> </ div> </ div> </ div> {% endblock %}{% block js %}< script> { % comment % } function votePost ( id, flag ) { is_up = flag === 'Digg' ? 0 : 1 ; } { % endcomment % } $ ( ".active" ) . click ( function ( ) { let is_up = $ ( this ) . hasClass ( 'diggit' ) ; var article_id = '{{ article_detail.pk }}' ; var _this = $ ( this ) ; $. ajax ( { url : '/up_and_down/' , type : 'post' , data : { is_up : is_up, article_id : article_id, csrfmiddlewaretoken : '{{ csrf_token }}' } , success : function ( ) { if ( res === 200 ) { $ ( "#digg_tips" ) . text ( res. msg) ; let old_num = _this. children ( ) . text ( ) ; { #_this. children ( ) . text ( parseInt ( old_num) + 1 ) ; #} _this. children ( ) . text ( Number ( old_num) + 1 ) ; } else { $ ( "#digg_tips" ) . html ( res. msg) ; } } , } ) ; } ) ; </ script>
{% endblock %}
2.后端
def up_and_down ( request) : '''分析点赞点彩的实现逻辑:1.必须判断用户是否登陆了。如果没有则在前端页面显示登录2.若是第一次登录:2.1 点赞数加 12.2 在页面上显示点赞成功3.如果已经点击过,就提示不让他再点了4.如果是第一次点击,应该在处理哪些逻辑4.1 肯定需要在点赞点彩表中增加一条记录4.2 还需要更新文章中的up_num或者down_num字段5. 取消点赞或者点彩功能-----》收藏:param request::return:''' if request. method == 'POST' : back_dict = { 'code' : 200 , 'msg' : '支持成功' } is_up = request. POST. get( 'is_UP' ) is_up = json. loads( is_up) article_id = request. POST. get( 'article_id' ) if not request. session. get( 'username' ) : back_dict[ 'code' ] = 1400 back_dict[ 'msg' ] = '请先<a href="/login/" style="color: red;">登录</a>' return JsonResponse( back_dict) res = models. UpAndDown. objects. filter ( article_id= article_id, user_id= request. session. get( 'id' ) ) . first( ) if res: back_dict[ 'code' ] = 1401 back_dict[ 'msg' ] = '你已经支持过了' return JsonResponse( back_dict) if is_up: models. Article. objects. create( pk= article_id) . update( up_num= F( 'up_num' ) + 1 ) else : models. Article. objects. filter ( pk= article_id) . update( down_num= F( 'down_num' ) + 1 ) back_dict[ 'msg' ] = '支持成功' models. UpAndDown. objects. create( is_up= is_up, article_id= article_id, user_id= request. session. get( 'id' ) ) return JsonResponse( back_dict)
四、评论功能
1.前端
{% extends 'home.html' %}{% block css %}< style> .s1 { margin-right : 10px; color : #999; } .content { font-size : 18px; color : #444; } #div_digg { float : right; margin-bottom : 10px; margin-right : 30px; font-size : 12px; width : 128px; text-align : center; margin-top : 10px; } .diggit { float : left; width : 46px; height : 52px; background : url ( /static/img/upup.gif) no-repeat; text-align : center; cursor : pointer; margin-top : 2px; padding-top : 5px; } .buryit { float : right; margin-left : 20px; width : 46px; height : 52px; background : url ( /static/img/downdown.gif) no-repeat; text-align : center; cursor : pointer; margin-top : 2px; padding-top : 5px; } .clear { clear : both; } .diggword { margin-top : 5px; margin-left : 0; font-size : 12px; color : #808080; } .clearfix:focus { content : '' ; display : block; clear : both; } </ style>
{% endblock %}{% block content %}< div class = " col-md-3" > < div class = " panel panel-info" > < div class = " panel-heading" > 文章分类</ div> < div class = " panel-body" > {% for category in category_list %}< p> < a href = " /{{ username }}/category/{{ category.2 }}" > {{ category.0 }} ({{ category.1 }})</ a> </ p> {# < p> < a href = " /{{ username }}/category/{{ category.pk }}" > {{ category.name }} ({{ category.count_article_num }})</ a> </ p> #}{% endfor %}</ div> </ div> < div class = " panel panel-success" > < div class = " panel-heading" > 文章标签</ div> < div class = " panel-body" > {% for tag in tag_list %}< p> < a href = " /{{ username }}/tag/{{ tag.2 }}" > {{ tag.0 }} ({{ tag.1 }})</ a> </ p> {% endfor %}</ div> </ div> < div class = " panel panel-danger" > < div class = " panel-heading" > 日期归档</ div> < div class = " panel-body" > {% for date in date_list %}{# < p> < a href = " " > {{ date.0 }} ({{ date.1 }})</ a> </ p> #}< p> < a href = " /{{ username }}/archive/{{ date.month|date:'Y-m' }}" > {{ date.month|date:'Y年m月' }}({{ date.count_article_nums }})</ a> </ p> {% endfor %}</ div> </ div> </ div> < div class = " col-md-9" > < h3 style = " color : #399ab2; " > {{ article_detail.title }}</ h3> < div class = " content" > {{ article_detail.content|safe }}</ div> < div class = " clearfix" > < div id = " div_digg" > < div class = " diggit active" onclick = " votePost ( 11647089 , 'Digg' ) " > < span class = " diggnum" id = " digg_count" > {{ article_detail.up_num }}</ span> </ div> < div class = " buryit active" onclick = " votePost ( 11647089 , 'Bury' ) " > < span class = " burynum" id = " bury_count" > {{ article_detail.down_num }}</ span> </ div> < div class = " clear" > </ div> < div class = " diggword" id = " digg_tips" style = " color : red; " > </ div> </ div> </ div> < div class = " comment_list" > < h3> < span class = " glyphicon glyphicon-comment" > </ span> 评论列表</ h3> < ul class = " list-group" > {% for comment in comment_list %}< li class = " list-group-item" > < span style = " margin-right : 10px; " > # {{ forloop.counter }}楼</ span> < span style = " margin-right : 10px; " > {{ comment.comment_time }}</ span> {# < span style = " margin-right : 10px; " > {{ comment.parent.user.username }}</ span> #}< span style = " margin-right : 10px; " > {{ comment.user.username }}</ span> < span style = " margin-right : 10px; " class = " pull-right" > < a href = " javascript:;" comment_username = " {{ comment.user.username }}" comment_id = " {{ comment.pk }}" class = " repay" > 回复</ a> </ span> < div class = " content" style = " margin-left : 14px; " > {% if comment.parent %}{{ comment.content }}{% else %}< p> @ {{ comment.parent.user.username }}</ p> < p> {{ comment.content }}</ p> {% endif %}</ div> </ li> {% endfor %}</ ul> </ div> < div class = " comment" > < p> < span class = " glyphicon glyphicon-comment" > </ span> 发表评论</ p> < p> < textarea name = " " id = " content" cols = " 30" rows = " 10" > </ textarea> </ p> < p> < button class = " btn btn-success comment_content" > 提交评论</ button> </ p> </ div> </ div> {% endblock %}{% block js %}< script> { % comment % } function votePost ( id, flag ) { is_up = flag === 'Digg' ? 0 : 1 ; } { % endcomment % } $ ( ".active" ) . click ( function ( ) { let is_up = $ ( this ) . hasClass ( 'diggit' ) ; var article_id = '{{ article_detail.pk }}' ; var _this = $ ( this ) ; $. ajax ( { url : '/up_and_down/' , type : 'post' , data : { is_up : is_up, article_id : article_id, csrfmiddlewaretoken : '{{ csrf_token }}' } , success : function ( ) { if ( res === 200 ) { $ ( "#digg_tips" ) . text ( res. msg) ; let old_num = _this. children ( ) . text ( ) ; { #_this. children ( ) . text ( parseInt ( old_num) + 1 ) ; #} _this. children ( ) . text ( Number ( old_num) + 1 ) ; } else { $ ( "#digg_tips" ) . html ( res. msg) ; } } , } ) ; } ) ; var parent_id = null ; < ! -- 评论功能开始 -- > $ ( ".comment_content" ) . click ( function ( ) { var article_id = '{{ article_detail.pk }}' ; var content = $ ( '#content' ) . val ( ) ; if ( parent_id) { let sub_number = content. indexOf ( '\n' + '' ) ; content = content. slice ( sub_number) ; } $. ajax ( { url : '/comment/' , type : 'post' , data : { article_id : article_id, content : content, parent_id : parent_id, csrfmiddlewaretoken : '{{ csrf_token }}' } , success : function ( res ) { var username = '{{ request.session.username }}' ; var html = ` <li class="list-group-item"><span style="margin-right: 10px;"><span class="glyphicon glyphicon-comment"></span> ${ username} </span><div class="content" style="margin-left: 14px;"> ${ content} </div></li> ` $ ( ".list-group" ) . append ( html) $ ( '#content' ) . val ( '' ) } , } ) ; } ) ; < ! -- 评论功能结束 -- > < ! -- 子评论功能开始 -- > $ ( ".repay" ) . click ( function ( ) { let comment_username = $ ( this ) . attr ( 'comment_username' ) ; parent_id = $ ( this ) . attr ( "comment_id" ) ; $ ( "#content" ) . val ( '@' + comment_username + '\n' ) . focus ( ) ; } ) ; < ! -- 子评论功能结束 -- > </ script>
{% endblock %}
2.后端
def comment ( request) : '''分析评论的逻辑:1.登录之后才能评论2.评论的内容要入库1.操作文章表,2.评论表:param request::return:''' back_dict = { 'code' : 200 , 'msg' : '支持成功' } article_id = request. POST. get( 'article_id' ) content = request. POST. get( 'content' ) parent_id = request. POST. get( 'parent_id' ) if not request. session. get( 'username' ) : back_dict[ 'code' ] = 1404 back_dict[ 'msg' ] = '请先登录之后再评论' return JsonResponse( back_dict) from django. db import transactiontry : with transaction. atomic( ) : models. Article. objects. filter ( pk= article_id) . update( comment_num= F( 'comment_num' ) + 1 ) models. Comment. objects. create( content= content, article_id= article_id, parent_id= parent_id, user_id= request. session. get( 'id' ) ) except : . . . transaction. rollback( ) return JsonResponse( back_dict)