Django:reverse反轉URL並傳遞參數


需求:

  假設在文章詳情頁評論文章后需要重新刷新顯示該頁面(原始方法,提交評論表單為form方式,未采用ajax方式),

提交評論后代碼會走comment的視圖函數,等數據入庫之后需要將頁面重新定位到文章詳情頁面。

article_detail2.html頁面

<!-- 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'),
]

 

 

評論視圖函數: 

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)

使用reverse函數(意思是逆向、反轉)代碼中只要寫對應url的name就實現了從name到path的轉換,那為什么叫反轉呢,因為URL配置中實現的是從path到name。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM