需求:html
假設在文章詳情頁評論文章後須要從新刷新顯示該頁面(原始方法,提交評論表單爲form方式,未採用ajax方式),ajax
提交評論後代碼會走comment的視圖函數,等數據入庫以後須要將頁面從新定位到文章詳情頁面。django
article_detail2.html頁面app
<!-- article_detail2.html --> <!-- 發表評論 --> <br> {% if user.is_authenticated %} <div> <form action="{% url 'comment:post_comment' article.id %}" method="POST" > {% csrf_token %} <div class="form-group"> <label for="body"> <strong> 我也要發言: </strong> </label> <textarea type="text" class="form-control" id="body" name="body" rows="2"></textarea> </div> <!-- 提交按鈕 --> <button type="submit" class="btn btn-primary ">發送</button> </form> </div> <br> {% else %} <br> <h5 class="row justify-content-center"> 請<a href="{% url 'account:user_login' %}">登陸</a>後回覆 </h5> <br> {% endif %}
URL路由函數
from django.conf.urls import url from . import views, list_views from haystack.views import SearchView urlpatterns=[ url(r'^article-column/$', views.article_column, name='article_column'), url(r'^rename-column/$', views.rename_article_column, name='rename_article_column'), url(r'^delete-column/$', views.delete_article_column, name='delete_column'), url(r'^post-article/$', views.article_post, name='article_post'), url(r'^article-list/$', views.article_list, name='article_list'), url(r'^delete-article/$', views.delete_article, name='delete_article'), url(r'^article-detail/(?P<id>\d+)/(?P<slug>[-\w]+)/$', views.article_detail, name='article_detail'), url(r'^re-edit-article/(?P<article_id>\d+)$', views.re_edit_article, name='re_edit_article'), url(r'^list-article-titles/$', list_views.article_titles, name='list_article_titles'), url(r'^list-article-titles-bysomeone/(?P<author>[-\w]+)/$', list_views.article_titles_by_someone, name='list_article_titles_bysomeone'), url(r'^upload/$', views.upload_img, name='upload_img'), # url(r'^search/$', views.MySeachView, name='haystack_search'), # SearchView()視圖函數,默認使用的HTML模板路徑爲templates/search/search.html url(r'search/$', SearchView(), name='haystack_search'), ]
評論視圖函數: post
from django.http import HttpResponse from django.shortcuts import render, get_object_or_404, redirect, reverse from article.models import ArticlePost from comment.forms import CommentForm from .models import Comment from utils.decorators import login_wrapper # Create your views here. # @login_wrapper def post_comment(request, article_id, parent_comment_id=None): article = get_object_or_404(ArticlePost, id=article_id) slug = article.slug print(article_id, parent_comment_id) # 處理post請求 if request.method == 'POST': comment_form = CommentForm(request.POST) if comment_form.is_valid(): new_comment = comment_form.save(commit=False) new_comment.article = article new_comment.user = request.user # 二級回覆 if parent_comment_id: print('已請求') parent_comment = Comment.objects.get(id=parent_comment_id) # 若回覆層級超過兩級,則轉爲二級 new_comment.parent_id = parent_comment.get_root().id # 被回覆人 new_comment.reply_to = parent_comment.user new_comment.save() print('評論已寫入') return HttpResponse('200 OK') new_comment.save() # 評論完成刷新該頁面,後面優化爲aja提交數據,局部刷新 # return redirect('article:list_article_titles') # reverse反轉url時須要傳參數,要用到kwargs參數,會傳入一個字典類型的參數 article_detail_url = reverse('article:article_detail', kwargs={'id': article_id, 'slug': slug}) return redirect(article_detail_url) else: return HttpResponse("表單有誤,從新填寫") elif request.method == 'GET': print('獲取評論') comment_form = CommentForm() context = { 'comment_form': comment_form, 'article_id': article_id, 'parent_comment_id': parent_comment_id } return render(request, 'comment/reply.html', context) else: return HttpResponse("僅接受get或者post請求")
其中能夠看到這兩行:優化
article_detail_url = reverse('article:article_detail', kwargs={'id':article_id,'slug':slug}) return redirect(article_detail_url)
在評論視圖中若是採用硬編碼方式則爲編碼
article_detail_url = 'article/article-detail/%s/%s' % (article_id,slug) return redirect(article_detail_url)
這樣作的壞處就是,若是當文章詳情頁面的url變化以後,這裏也要跟着修改,不符合DRY原則(Don`t Repeat Yourself)url
使用reverse函數(意思是逆向、反轉)代碼中只要寫對應url的name就實現了從name到path的轉換,那爲何叫反轉呢,由於URL配置中實現的是從path到name。spa