【发布时间】:2023-03-31 21:19:01
【问题描述】:
抱歉,如果标题不清楚,我不确定描述问题的最佳方式。我有一个带有Ticket 模型和Team 模型的应用程序。所有Tickets 都与一个Team 相关联。我遇到的问题是 URL 反转的问题。我正在尝试像这样设置我的 URL:/<team_pk>/tickets/ 显示与team_pk 指定的团队相关联的票证列表。所以/1/tickets/ 将显示第一支球队的所有门票。这两个对象都在应用程序tracker中。
为此,我设置了我的 project/urls.py 文件,如下所示:
project/urls.py
urlpatterns = [ path('<team_pk>/', include('tracker.urls', namespace='tracker')), ]
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 %}"
这会产生所需的行为,但会重复很多。那么,有没有更好的办法呢?
编辑:
根据 Willem Van Onsem 的建议,我将 URL 模板标签更改为 href="{% url 'tracker:ticket_list' team_pk=team_pk %}",直接引用 URL kwarg。但这似乎并不可靠。在索引页面上/<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 确实起作用。
【问题讨论】:
-
否,但您不必扩展
get_context_data,因为命名的 URL 参数也会直接传递给模板。