BBS專案分佈搭建三(個人站點時間歸檔補充,實現側邊欄跳轉、無線級分類、實現文章詳情頁展示功能)
阿新 • • 發佈:2022-03-16
BBS專案分佈搭建三(個人站點時間歸檔補充,)
1. 個人站點時間歸檔
""" settings.py設定最好更改以下: LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' USE_TZ = False # 資料庫時間 """ # 在 blog.html檔案中修改: <div class="panel panel-danger"> <div class="panel-body"> 時間歸檔 </div> {% for date in date_list %} <div class="panel-footer"> <a href="">{{ date.month|date:'Y-m' }}({{ date.c }})</a> </div> {% endfor %} </div> # 在views.py中修改個人站點功能: # 7.個人站點頁 def blog(request, username): ''' 驗證站點是否存在 :param request: :param username: :return: ''' # 驗證站點的存在性 404頁面 user_obj = models.UserInfo.objects.filter(username=username).first() if not user_obj: # 應該返回定製的404頁面 return render(request, '404.html') blog = user_obj.blog # 個人站點 # 查詢當前站點的所有文章列表 article_list = models.Article.objects.filter(blog=blog).all() '''查詢當前站點下的所有標籤''' # 第一步: tag_list = models.Tag.objects.filter(blog=blog).all() # print(tag_list) # 第二步:聚合查詢每一個標籤下的文章數量 ''' 聚合查詢使用關鍵字annotate 分組查詢使用關鍵字aggreate ''' from django.db.models import Count # tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list('title', 'count_num') # tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article')).values_list('title', 'count_num') tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article')).values('title', 'count_num') # print(tag_list) '''查詢當前站點下的所有分類''' category_list = models.Category.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values('title', 'count_num') # print(category_list) '''把當前站點下的文章按照年月分組,並且查詢分組下的文章數量''' from django.db.models.functions import TruncMonth # 1. 查的是新增文章的時間:年月 # 2. 查詢分組之後的文章數量 # 3. month => 2021-06 => 虛擬欄位 date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values('month').annotate(c=Count('id')).values('month', 'c') print(date_list) return render(request, 'blog.html', locals())
2. 實現側邊欄篩選跳轉功能
# 新增路由: # 側邊欄篩選功能 # url(r'^(?P<username>\w+)/tag/(?P<param>\d+)', views.blog), # 標籤 # url(r'^(?P<username>\w+)/category/(?P<param>\d+)', views.blog), # 分類 # url(r'^(?P<username>\w+)/archive/(?P<param>\w+)', views.blog), # 分類 # 以上三個地址可以合併為一個地址 url(r'^(?P<username>\w+)/(?P<conditon>tag|category|archive)/(?P<param>.*)', views.blog), # 修改個人站點功能: # 7.個人站點頁 def blog(request, username, **kwargs): print(123) ''' 驗證站點是否存在 :param request: :param username: :return: ''' # 驗證站點的存在性 404頁面 user_obj = models.UserInfo.objects.filter(username=username).first() if not user_obj: # 應該返回定製的404頁面 return render(request, '404.html') blog = user_obj.blog # 個人站點 # 查詢當前站點的所有文章列表 article_list = models.Article.objects.filter(blog=blog).all() # 側邊欄少選功能 if kwargs: # print(kwargs) # {'conditon': 'tag', 'param': '2'} # print(kwargs) # {'conditon': 'category', 'param': '1'} # print(kwargs) # {'conditon': 'archive', 'param': '2022-03'} conditon = kwargs.get('conditon') param = kwargs.get('param') if conditon == 'tag': # 按照標籤篩選 article_list = article_list.filter(tags__pk=param) elif conditon == 'category': # 按照分類進行篩選 article_list = article_list.filter(category__id=param) else: # 按照時間篩選 # 2022-03 year, month = param.split('-') # [2022, 03] article_list = article_list.filter(create_time__year=year, create_time__month=month) '''查詢當前站點下的所有標籤''' # 第一步: tag_list = models.Tag.objects.filter(blog=blog).all() # print(tag_list) # 第二步:聚合查詢每一個標籤下的文章數量 ''' 聚合查詢使用關鍵字annotate 分組查詢使用關鍵字aggreate ''' from django.db.models import Count # tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list('title', 'count_num') # tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article')).values_list('title', 'count_num') tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article')).values('title', 'count_num', 'pk') # print(tag_list) '''查詢當前站點下的所有分類''' category_list = models.Category.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values('title', 'count_num', 'pk') # print(category_list) '''把當前站點下的文章按照年月分組,並且查詢分組下的文章數量''' from django.db.models.functions import TruncMonth # 1. 查的是新增文章的時間:年月 # 2. 查詢分組之後的文章數量 # 3. month => 2021-06 => 虛擬欄位 date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values('month').annotate(c=Count('id')).values('month', 'c') # print(date_list) return render(request, 'blog.html', locals()) # 修改 blog.html檔案 <div class="col-md-3"> : <div class="col-md-3"> <div class="panel panel-primary"> <div class="panel-body"> 我的標籤 </div> {% for tag in tag_list %} <div class="panel-footer"> <a href="/{{ username }}/tag/{{ tag.pk }}">{{ tag.title }}( {{ tag.count_num }})</a> </div> {% endfor %} </div> <div class="panel panel-success"> <div class="panel-body"> 我的分類 </div> {% for category in category_list %} <div class="panel-footer"> <a href="/{{ username }}/category/{{ category.pk }}">{{ category.title }}({{ category.count_num }})</a> </div> {% endfor %} </div> <div class="panel panel-danger"> <div class="panel-body"> 時間歸檔 </div> {% for date in date_list %} <div class="panel-footer"> <a href="/{{ username }}/archive/{{ date.month|date:'Y-m'}}">{{ date.month|date:'Y-m' }}({{ date.c }})</a> </div> {% endfor %} </div> </div>
3. 無限級 分類實現
# 利用新欄位 pid >> parent_id 父id
給下一級的標題增加pid 就可以形成無限級分類
# 此外 紅黑樹資料結構 也可以實現
4. 文章詳情頁
# 新建公共HTML檔案用於模板繼承 base.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> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <script src="/static/layer-v3.5.1/layer/layer.js"></script> <style> #wrapper span { margin-right: 10px; } </style> </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="#">py20BBS</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="#">Link <span class="sr-only">(current)</span></a></li> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <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.session.username %} <li><a href="#">{{ request.session.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=".bs-example-modal-lg">修改密碼</a></li> <li><a href="#">後臺管理</a></li> <li><a href="/logout/">退出系統</a></li> </ul> </li> {% else %} <li><a href="/register/">註冊</a></li> <li><a href="/login/">登入</a></li> {% endif %} </ul> </div><!-- /.navbar-collapse --> <div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="row"> <h1 class="text-center">修改密碼</h1> <div class="col-md-8 col-md-offset-2"> <div class="form-group"> <label for="old_pwd"> 原密碼: </label> <input type="text" id="old_pwd" class="form-control"> </div> <div class="form-group"> <label for="new_pwd"> 新密碼: </label> <input type="text" id="new_pwd" class="form-control"> </div> <div class="form-group"> <label for="re_pwd">確認密碼:</label> <input type="text" id="re_pwd" class="form-control"> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">取消</button> <button type="button" class="btn btn-primary set_pwd">提交</button> </div> </div> </div> </div> </div> </div> </div><!-- /.container-fluid --> </nav> <div class="container-fluid"> <div class="row"> <div class="col-md-3"> <div class="panel panel-primary"> <div class="panel-body"> 我的標籤 </div> {% for tag in tag_list %} <div class="panel-footer"> <a href="/{{ username }}/tag/{{ tag.pk }}">{{ tag.title }}( {{ tag.count_num }})</a> </div> {% endfor %} </div> <div class="panel panel-success"> <div class="panel-body"> 我的分類 </div> {% for category in category_list %} <div class="panel-footer"> <a href="/{{ username }}/category/{{ category.pk }}">{{ category.title }}({{ category.count_num }})</a> </div> {% endfor %} </div> <div class="panel panel-danger"> <div class="panel-body"> 時間歸檔 </div> {% for date in date_list %} <div class="panel-footer"> <a href="/{{ username }}/archive/{{ date.month|date:'Y-m'}}">{{ date.month|date:'Y-m' }}({{ date.c }})</a> </div> {% endfor %} </div> </div> <div class="col-md-9"> {% block content %} {% endblock %} </div> </div> </div> </body> </html> # blog.html就可以直接繼承 base.html: {% extends 'base.html' %} {#// 模板繼承#} {#下面為動態內容#} {% block content %} {% for article in article_list %} <div class="media"> <h4 class="media-heading"><a href="">{{ article.title }}</a></h4> <div class="media-body"> {{ article.desc }} </div> <div id="wrapper" class="pull-right" style="margin-top: 15px"> <span>posted</span> <span>@</span> <span>{{ article.create_time|date:'Y-m-d H:i' }}</span> <span class="glyphicon glyphicon-thumbs-up">{{ article.up_num }}</span> <span class="glyphicon glyphicon-thumbs-down">{{ article.down_num }}</span> <span class="glyphicon glyphicon-comment">{{ article.comment_num }}</span> </div> </div> {% endfor %} {% endblock %} # 建立文章詳情頁 article_detail.html: {% extends 'base.html' %} {% block content %} <h1>{{ article_detail.title }}</h1> <div class="article_content"> {{ article_detail.content|safe }} </div> {% endblock %} # 新增路由 路由放在側邊篩選路由上方 避免正則匹配不到: # 文章詳情頁 url(r'^(?P<username>\w+)/(?P<article_id>\d+)', views.article_detail), # 新增文章詳情頁功能 views.py中: from django.db.models import Count # 8. 文章詳情頁 def article_detail(request, username, article_id): user_obj = models.UserInfo.objects.filter(username=username).first() if not user_obj: return render(request, '404.html') blog = user_obj.blog # 個人站點 # 查詢文章詳情資料 article_detail = models.Article.objects.filter(pk=article_id, blog=blog).first() if not article_detail: return render(request, '404.html') tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article')).values('title', 'count_num', 'pk') '''查詢當前站點下的所有分類''' category_list = models.Category.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values('title', 'count_num', 'pk') '''把當前站點下的文章按照年月分組,並且查詢分組下的文章數量''' from django.db.models.functions import TruncMonth # 1. 查的是新增文章的時間:年月 # 2. 查詢分組之後的文章數量 # 3. month => 2021-06 => 虛擬欄位 date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values('month').annotate(c=Count('id')).values('month', 'c') return render(request, 'article_detail.html', locals())