如何为Django Viewflow flowurl模板标签传递asset_pk等kwargs参数?
问题描述
我正在使用django-viewflow,通过自定义视图展示库存物品记录,每个记录可关联多个工作流(注册/发放/处置等)。在记录详情页中,我希望列出该物品关联的所有工作流及其相关任务。
期望URL结构
.../asset/3/- 详情页.../asset/3/register/93/- 注册流程(及后续任务).../asset/3/movement/1/- 转移流程(及后续任务)- 其他类似结构
当前URL配置代码
asset_urls = FlowViewSet(AssetFlow).urls movement_urls = FlowViewSet(MovementFlow).urls app_name = 'asset' workflowurlpatterns = [ # path('ajax/load-budget_lines/', views.load_budget_lines, name='ajax_load_budget_lines'), path('viewflow/', include((asset_urls, 'asset'))), path('movement/', include((movement_urls, 'movement'))), # path('', views.Detail.as_view(), name='detail'), ] urlpatterns = [ path('', views.List.as_view(), name='assets'), path('<int:asset_pk>/', views.Detail.as_view(), name='detail'), path('<int:asset_pk>/', include((workflowurlpatterns))) ]
遇到的问题
使用模板标签{% flowurl task user=request.user as task_url %}生成所有URL时,均触发NoReverseMatch错误。
错误示例:
Reverse for 'finance_tc' with keyword arguments '{'process_pk': 93, 'task_pk': 411}' not found. 1 pattern(s) tried: ['asset/(?P<asset_pk>[0-9]+)/register/(?P<process_pk>\\d+)/finance_tc/(?P<task_pk>\\d+)/$']
请问是否有巧妙的方法传递asset_id以让URL正常工作(或其他解决方案)?
解决方案
1. 给流程模型绑定资产ID
首先确保你的AssetFlow、MovementFlow对应的流程模型(比如AssetProcess、MovementProcess)里添加asset外键或者asset_pk字段,让每个流程实例都能关联到对应的资产ID,这是后续传递参数的基础。
2. 自定义flowurl模板标签
默认的flowurl不会自动携带asset_pk这类额外参数,你可以自己写一个模板标签,从流程实例里取出资产ID并补充到URL参数中:
# 在你的app的templatetags目录下创建flow_extras.py from django import template from viewflow.templatetags.viewflow import FlowUrlNode register = template.Library() class AssetFlowUrlNode(FlowUrlNode): def get_url_kwargs(self, context): kwargs = super().get_url_kwargs(context) task = self.task.resolve(context) # 假设流程模型里有asset字段,取出对应的pk kwargs['asset_pk'] = task.process.asset.pk return kwargs @register.tag(name='asset_flowurl') def asset_flowurl(parser, token): node = AssetFlowUrlNode.parse(parser, token) return node
之后在模板里替换成自定义标签使用:
{% load flow_extras %} {% asset_flowurl task user=request.user as task_url %}
3. 调整URL命名空间(优化结构)
把原URL配置里的path('viewflow/', include((asset_urls, 'asset')))改成path('register/', include((asset_urls, 'register'))),这样URL结构会和你期望的/asset/3/register/...完全匹配,避免命名空间混淆。
4. 手动拼接URL(应急方案)
如果自定义标签嫌麻烦,也可以在模板里手动拼URL,直接传入所需参数:
{% url 'asset:register:finance_tc' asset_pk=task.process.asset.pk process_pk=task.process.pk task_pk=task.pk %}
这种方式需要明确知道每个任务的URL名称,适合临时场景。
内容的提问来源于stack exchange,提问作者dj.bettega
相关产品推荐
相关产品推荐

