python - Django:将 URL 参数传递给模板标签中反向 URL 查找的每个实例
问题描述
抱歉,如果标题不清楚,我不确定描述问题的最佳方式。我有一个带有Ticket
模型和Team
模型的应用程序。所有Ticket
s 都与单个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 %}"
这会产生所需的行为,但需要大量重复。那么,有没有更好的方法呢?
编辑:
根据 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>[^/]+)/$']
似乎由于<team_pk>
某种原因没有通过 URL kwarg。但唯一的链接'home'
是 my 的一部分,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 不可用的情况添加一些额外的逻辑。
推荐阅读
- swift - 如何在swift中生成带有参数的QRCode图像?
- apache-spark - spark sql可以创建nosql表吗?
- c# - LineGeometry 上奇怪的 StrokeDashArray 行为
- android-fragments - 单击列表视图中的项目时导航到新片段
- javascript - Three.js - TypeError: THREE.XLoader 不是构造函数
- ios - Firebase 身份验证中的 MultiFactor 是什么意思
- xcode - Safari 14:chrome.permissions.request() 无法无缝运行,并且 tab.url 总是空白 - 扩展
- java - 为什么 Java 使用带有 Dagger 的 HashMap 会抛出 NullPointerException?
- vba - 文本到表格,在不是段落标记的分隔符处创建行(不是列)
- python - 如何运行下载的 django 项目?