DRF不反转Django网址格式:NoReverseMatch

时间:2019-03-05 11:51:30

标签: python django django-rest-framework

有一个复杂的应用程序(无法仅粘贴代码)。要尝试解释。

Django

本地Django应用中有一个urls.py文件。 urlpatterns定义并注册其URL。 ^foo/定义了一组相关的URL和foonamepsace

urlpatterns = patterns('',
                       ...
                       url(r'^foo/', include('foo.urls', namespace='foonamespace')),
                       ...

现在有一种方法generate_report,该方法在内部进行一些逻辑处理,然后使用render_to_string返回HTML:

def generate_report(..):
    ...
    return render_to_string('foo/foo_report.html', args)

所有内容都可以在应用程序中正常运行,URL成功撤消。

Django Rest Framework(DRF)

现在有一个DRF实现,并且它的资源之一应该以二进制格式返回报告。

class PDFReportViewSet(APIView):
    renderer_classes = (BinaryFileRenderer, )

    def get(..):
        ...
        pdf = generate_report()  # <-- fails with NoReverseMatch
        ...
        return response

问题

ViewSet调用generate_report,但是在尝试解析HTML时会出错:

  

NoReverseMatch:foonamespace'不是注册的名称空间

问题

任何线索为何DRF无法从Django应用程序的核心中反转namepcae / url?如何确保DRF可以从核心urls.py urlpattern撤消命名空间?

已添加

经过调查,在foo_report.html内使用该URL的任何方式(例如{% url 'foonamespace:123' %}{% url 'barnamespace:123' %}都会产生错误-仅当从DRF运行时(使用本机Django运行同一页面效果很好)。

URLS

foo.urls.py

from django.conf.urls import patterns, url
from foo.views import (FooListView, FooDetailView...)

urlpatterns = patterns('',
                       url(r'^$', FooListView.as_view(), name='foo_list'),
                       url(r'^(?P<pk>\d+)/$', FooDetailView.as_view(), name='foo_details'),

重要说明。该应用程序在 some.domain.com / 中提供,而REST从 some.domain.com/rest 中提供。因此,/rest可能不包含任何内容,因为它是根的父级(包括foo.urls.py

1 个答案:

答案 0 :(得分:1)

在@dirkgroten的帮助下,我得以解决了自己的问题。不查看源代码就很难发现问题。

解决方案

更新了routers.py文件:

urlpatterns = router.urls
urlpatterns += patterns('',
                        url(r'^foo/', include('foo.urls', namespace='foonamespace')),
                        )

说明

基本上,该应用是从根URL /提供的,而其余部分是从/rest提供的。 DRF路由器根本不包含任何根路由。像solution中所示手动添加它们可以解决问题,并使foonamespace对于所有DRF元素可见。