簡體   English   中英

Django:將 URL 參數傳遞給模板標簽中反向 URL 查找的每個實例

[英]Django: passing a URL parameter to every instance of a reverse URL lookup in a template tag

抱歉,如果標題不清楚,我不確定描述問題的最佳方式。 我有一個帶有Ticket model 和Team model 的應用程序。 所有Ticket都與一個Team相關聯。 我遇到的問題是 URL 倒車的問題。 我正在嘗試像這樣設置我的 URL: /<team_pk>/tickets/顯示與team_pk指定的團隊相關聯的票證列表。 所以/1/tickets/將顯示第一個團隊的所有門票。 這兩個對象都在 app tracker中。

為此,我設置了我的 project/urls.py 文件,如下所示:

項目/urls.py

urlpatterns = [ path('<team_pk>/', include('tracker.urls', namespace='tracker')), ]

跟蹤器/urls.py

urlpatterns = [ path('tickets/', views.TicketTable.as_view(), name='ticket_list'), ]

然后,在我的 html 模板中,我有以下 URL 標簽:

href="{% url 'tracker:ticket_list' %}"

這會導致 NoReverseMatch 錯誤:

NoReverseMatch at /1/tickets/
Reverse for 'ticket_list' with no arguments not found. 1 pattern(s) tried: ['(?P<team_pk>[^/]+)/tickets/$']

我想要的是反向匹配只使用team_pk URL kwarg 的當前值。

我試圖解決的問題:

我找到了以下解決問題的方法,但是它涉及到很多重復,我覺得必須有一個 DRYer 的方式。

首先,我為站點上的每個視圖擴展了get_context_data()方法。

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['current_team_pk'] = self.kwargs['team_pk']
    return context

然后我在每個 URL 模板標簽中引用這個上下文:

href="{% url 'tracker:ticket_list' team_pk=current_team_pk %}"

這會產生所需的行為,但需要大量重復。 那么,有沒有更好的方法呢?

編輯:

Based on Willem Van Onsem's suggestion, I changed the URL template tag to href="{% url 'tracker:ticket_list' team_pk=team_pk %}" , referencing the URL kwarg directly. 但這似乎並不可靠。 在索引頁面上/<team_pk>/加載得很好,它包括兩個相關的 URL: /<team_pk>//<team_pk>/tickets/ 但是,當我導航到/<team_pk>/tickets/時,我收到另一個 NoReverseMatch 錯誤:

NoReverseMatch at /1/tickets/
Reverse for 'home' with keyword arguments '{'team_pk': ''}' not found. 1 pattern(s) tried: ['(?P<team_pk>[^/]+)/$']

似乎 URL kwarg <team_pk>由於某種原因沒有通過。 但是到'home'的唯一鏈接是我的base.html的一部分,其他模板正在擴展。 所以相關的模板標簽是一樣的。

編輯2:

有問題的觀點:

class TicketTable(LoginRequiredMixin, SingleTableMixin, FilterView):
    table_class = my_tables.TicketTable
    template_name = 'tracker/ticket_list.html'
    filterset_class = TicketFilter
    context_object_name = 'page'
    table_pagination = {"per_page": 10}
    PAGE_TITLE = 'Open Tickets'
    TICKET_STATUS_TOGGLE = 'Show Closed Tickets'
    TICKET_STATUS_TOGGLE_URL = 'tracker:closed_ticket_list'
    DISPLAY_DEV_FILTER = True
    DISPLAY_STATUS_FILTER = True

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['page_title'] = self.PAGE_TITLE
        context['ticket_status_toggle'] = self.TICKET_STATUS_TOGGLE
        context['ticket_status_toggle_url'] = self.TICKET_STATUS_TOGGLE_URL
        context['display_dev_filter'] = self.DISPLAY_DEV_FILTER
        context['display_status_filter'] = self.DISPLAY_STATUS_FILTER
        return context

    def get_queryset(self):
        return models.Ticket.objects.filter_for_team(self.kwargs['team_pk']).filter_for_user(self.request.user).exclude(status='closed')

編輯3:

我找到了一種無需修改上下文數據即可訪問 URL kwargs 的解決方案。 我不確定為什么team_pk=team_pk在 URL 標簽中不起作用,但team_pk=view.kwargs.team_pk確實起作用。

根據我的朋友 Willem Van Onsem 的評論和回復,以及我自己的一些挖掘,我發現了我認為最干的方法來做我想做的事情。 我創建了一個自定義 mixin:

class CommonTemplateContextMixin:
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        if self.kwargs.get('team_pk'):
            context.setdefault('team_pk', self.kwargs.get('team_pk'))
        else:
            context.setdefault('team_pk', self.request.user.teams.all()[0].pk)
        return context

然后我用我所有的觀點對這個 mixin 進行子類化。 然后我的所有模板中都有一個team_pk模板標簽,我只需將team_pk=team_pk添加到我所有的 URL 模板標簽中。 使用它而不是team_pk=view.kwargs.team_pk的唯一優點是,當 URL kwarg 不可用時,我可以添加一些額外的邏輯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM