0

我遇到了一个错误:

Reverse for 'detail' not found. 'detail' is not a valid view function or pattern name.

当我试图覆盖AssignTaskView视图时。

这样做的理由是允许我的用户将任务重新分配给其他人,而不必生成单独的任务来执行此操作,以及放入我的自定义表单以显示可供选择的用户的 lsit。

我的大部分灵感来自这篇特定的帖子:

使用自定义上下文覆盖 django 视图(Django 1.11,Viewflow)

这是我的代码:

网址.py

它实际上允许我覆盖和显示我自己的表单。

    path('pipeline/<process_pk>/documents/<task_pk>/assign/', OverrideTaskView.as_view(), {
     'flow_class': Pipeline,
     'flow_task': Pipeline.documents
}),

问题出在这里:

视图.py

class OverrideTaskView(AssignTaskView,FormView):
form_class=AssignForm

def get_form_kwargs(self):
    kwargs = super(OverrideTaskView, self).get_form_kwargs()
    kwargs.update({'id': self.request.user})
    return kwargs

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

def form_valid(self, form):
    if '_assign' or '_continue' in request.POST:
        form.save(commit=False)
        assigned = form.cleaned_data.get('user')
        self.activation.assign(assigned)
        self.success(_('Task {task} has been assigned'))
        return HttpResponseRedirect(self.get_success_url())
    else:
        return self.get(request, *args, **kwargs)

我怀疑它与 get_success_url 有关?单击确认按钮后才弹出错误,请帮助!

编辑

这是从我的调试页面中找到的 URL 模式:

^pipeline/(?P<process_pk>\d+)/documents/(?P<task_pk>\d+)/assign/$ 
[name='documents__assign']
pipeline/ ^archive/$ [name='archive']
pipeline/ ^action/cancel/(?P<process_pk>\d+)/$ [name='action_cancel']
pipeline/ ^(?P<process_pk>\d+)/$ [name='detail']   #<--- its here!!

完整的错误追溯

Internal Server Error: /pipeline/35/documents/195/assign/
Traceback (most recent call last):
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\site-packages\django\views\generic\base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\site-packages\django\utils\decorators.py", line 43, in _wrapper
    return bound_method(*args, **kwargs)
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\contextlib.py", line 75, in inner
    return func(*args, **kwds)
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\site-packages\viewflow\decorators.py", line 213, in _wrapper
    return view(request, **kwargs)
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\site-packages\viewflow\flow\views\task.py", line 197, in dispatch
    return super(AssignTaskView, self).dispatch(request, *args, **kwargs)
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\site-packages\django\views\generic\base.py", line 97, in dispatch
    return handler(request, *args, **kwargs)
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\site-packages\viewflow\flow\views\task.py", line 175, in post
    self.success(_('Task {task} has been assigned'))
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\site-packages\viewflow\flow\views\mixins.py", line 90, in success
    self.report(message, level=messages.SUCCESS, fail_silently=fail_silently, **kwargs)
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\site-packages\viewflow\flow\views\mixins.py", line 69, in report
    process_url = reverse('{}:detail'.format(namespace), args=[self.activation.process.pk])
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\site-packages\django\urls\base.py", line 87, in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
  File "C:\Users\Dion Neo Wen Shun\AppData\Local\Programs\Python\Python38\lib\site-packages\django\urls\resolvers.py", line 677, in _reverse_with_prefix
    raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'detail' not found. 'detail' is not a valid view function or pattern name.
[08/Apr/2020 22:37:24] "POST /pipeline/35/documents/195/assign/ HTTP/1.1" 500 129534

我真的不知道发生了什么!

4

2 回答 2

0

我尝试安装 django-extensions 并使用了 show_urls 方法。这告诉我命名与其他命名略有不同,例如:

这是我覆盖的 URL:

/pipeline/<process_pk>/documents/<task_pk>/assign/      cash.views.OverrideTaskView     cash:documents__assign

这是原始网址

/pipeline/<process_pk>/documents/<task_pk>/assign/      viewflow.flow.views.task.AssignTaskView cash:pipeline:documents__assign

因此在我的项目中的 urls.py 中(不是根 url 配置)

我在此添加了覆盖的 URL

path('pipeline/<process_pk>/documents/<task_pk>/assign/',
    OverrideTaskView.as_view(),
    {'flow_class': Pipeline,
    'flow_task': Pipeline.documents},
    name="pipeline:{}__assign".format(Pipeline.documents.name)),

然而这并没有解决问题。

我在自定义分配视图中添加了一条打印语句:

print(self.request.resolver_match.namespace)

它给了我:

cash

这是错误的,因为它应该是:

cash:pipeline

因此系统试图搜索错误目录前面的 URL?(我假设)

无论如何,我通过将其放入获取成功 url 解决了这个问题:

    def get_success_url(self):
    """Continue on task or redirect back to task list."""
    url = self.activation.flow_task.get_task_url(
        self.activation.task, url_type='guess', user=self.request.user,
        namespace=self.request.resolver_match.namespace + ':' + 'pipeline')

    back = self.request.GET.get('back', None)
    if back and not is_safe_url(url=back, allowed_hosts={self.request.get_host()}):
        back = '/'

    if '_continue' in self.request.POST and back:
        url = "{}?back={}".format(url, urlquote(back))
    elif back:
        url = back

    return url
于 2020-04-09T09:54:59.547 回答
0

要覆盖分配视图,您可以传递assign_view_class给 View 构造函数,例如

flow.View(..., assign_view=MyView.as_view())

或者创建一个自定义节点,assign_view_class重新定义属性 - https://github.com/viewflow/viewflow/blob/master/demo/shipment/flows.py#L57

于 2021-01-26T04:44:52.360 回答