使用 Django/Django.js 和 WSGIScriptAlias 进行 URL 反向

Posted

技术标签:

【中文标题】使用 Django/Django.js 和 WSGIScriptAlias 进行 URL 反向【英文标题】:URL Reverse with Django/Django.js and WSGIScriptAlias 【发布时间】:2014-12-28 10:58:08 【问题描述】:

我在生产环境中的 django 项目有问题。当我为“WSGIScriptAlias”apache 指令使用别名时,看起来我遇到了反向 URL 的问题。事实上,这个问题可能与django.js 模块有关,因为它似乎没有考虑到“WSGIScriptAlias”。

所以,这是我的 apache 配置:

<VirtualHost *:80>
    DocumentRoot /MyPath/django_proj/pti/pti
    WSGIScriptAlias /pti /MyPath/django_proj/pti/pti/pti_project/wsgi.py

    WSGIDaemonProcess pti python-path=/MyPath/django_proj/pti/pti:/MyPath/django_proj/pti/lib/python2.7/site-packages
    WSGIProcessGroup pti

    Alias /media/ /MyPath/django_proj/pti/pti/media_root/
    Alias /static/ /MyPath/django_proj/pti/pti/static_root/

    ErrorLog /var/log/apache2/pti-error_log
    <Directory /MyPath/django_proj/pti/pti/pti_project/>
            <Files wsgi.py>
                    Allow from all  
            </Files>
    </Directory>

    <Directory /MyPath/django_proj/pti/pti/static_root/>
            Order deny,allow
            Allow from all
    </Directory>

    <Directory /MyPath/django_proj/pti/pti/media_root/>
            Order deny,allow
            Allow from all
    </Directory>

如您所见,我的 WSGIScriptAlias 是“/pti”。

我的 django 网址是:

urlpatterns = patterns('',
# Examples:
# url(r'^$', 'pti_project.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),

url(r'^admin/', include(admin.site.urls)),
url(r'^djangojs/', include('djangojs.urls')),
url(r'^pti_core/', include('pti_core.urls', namespace='pti_core', app_name='pti_core')),
url(r'^pti_map/', include('pti_map.urls',  namespace='pti_map', app_name='pti_map')),
)

这部分似乎工作正常。但是当我使用url's reverse django.js 函数来获取我的数据时,问题就来了。这是我存储数据的 url 的 pti_map 配置文件:

urlpatterns = patterns('pti_map.views',
url(r'^$', 'map_index', name='map_index'),
url(r'^ptiretrait.geojson$', MapLayer.as_view(model=PtiRetrait), name='ptiretrait'),
url(r'^ptiencours.geojson$', MapLayer.as_view(model=PtiEnCours), name='ptiencours'),
url(r'^ptinouvelle.geojson$', GeoJSONLayerView.as_view(model=PtiNvlleDetection, precision = 5, simplify=0.5,  properties  = ('etat', 'friche', 'age', 'acces', 'culture', 'bati', 'voisinage', 'defrichement', 'mecanisable', 'irrigable', 'commentaire')), name='ptinouvelle'),
url(r'^newptisubmit$', 'newptisubmit', name='newptisubmit'),
url(r'^newptiedit$', 'newptiedit', name='newptiedit'),
url(r'^newptimodifygeom$', 'newptimodifygeom', name='newptimodifygeom'),
url(r'^ptiTable$', 'ptiTable', name='ptiTable'),
url(r'^sendEmail$', 'sendEmail', name='sendEmail'),
url(r'ajax_file_upload$', 'ajax_file_upload', name="ajax_file_upload"),
)

当我尝试使用此函数获取反向 URL 时,它似乎没有考虑到我的 WSGIScriptAlias。所以使用 django.js 的反向 urls 函数,结果为 Django.url('pti_map:ptinouvelle') 是:

http://MyServer/pti_map/ptinouvelle.geojson

而不是我所期望的:

http://MyServer/pti/pti_map/ptinouvelle.geojson

我可以确认“django.js”似乎没有考虑到我的 WSGIScriptAlias。这是我的console.log(Django.urls) 的结果:

pti_map:ptiencours "/pti_map/ptiencours.geojson"

pti_map:ptinouvelle "/pti_map/ptinouvelle.geojson"

pti_map:ptiretrait "/pti_map/ptiretrait.geojson"

如果我想让它工作,我必须在我的 JS 文件中硬编码 WSGIScriptAlias:

var url = "/pti" + Django.url('pti_map:ptinouvelle')

通过在 URL 的开头添加“/pti”,我可以获得我的数据,但这是一个丑陋的 hack,它破坏了我与我的开发平台的兼容性。

你知道我该如何解决这个问题吗?

谢谢。

阿诺

【问题讨论】:

【参考方案1】:

这仅仅是因为您的 Django 应用程序不知道您的 Web 服务器正在执行的重写或路由,它超出了它的范围。

你可能已经做了别名,因为你想在其他路由上托管其他东西。如果是这种情况,那么您可以做的是,您可以在内部将请求路由到 /pti_map 到 /pti_map/pti_map 并使用别名 /pti_map 到您的脚本。

在将请求路由到脚本时会做什么,wsgi 容器将吃掉第一个“pti_map”并转发下一个。

希望我理解正确。

【讨论】:

以上是关于使用 Django/Django.js 和 WSGIScriptAlias 进行 URL 反向的主要内容,如果未能解决你的问题,请参考以下文章

WSG-50E上网行为管理网关评测

AngularJS 将地理坐标从 Lambert 2 转换为 WSG84

WSG-200E上网行为管理网关开箱测评

千兆上网行为管理路由评测

将 MSSQL 中用于 Web 映射(Leaflet、Openlayer、OpenStreetMaps、GoogleAPI 等)的投影更改为 WSG48 或任何其他格式

无线设备的流控方案,记录WSG-500E的一次组网应用。