简体   繁体   English

Django 1.3 URL 重写

[英]Django 1.3 URL rewriting

Django has CommonMiddleware setup, which by default appends a slash to URLs that do not end with one. Django 具有 CommonMiddleware 设置,默认情况下会在不以 1 结尾的 URL 上附加一个斜杠。

For example: (1) http://www.example.com/admin is rewritten to (2) http://www.example.com/admin/ if it detects in the URLconf that /admin/ exists.例如: (1) http://www.example.com/admin被重写为 (2) http://www.example.com/admin/如果它在 URLconf 中检测到 /admin/ 存在。

However, I am getting the situation where instead of (2), I am getting (3) http://www.example.com//admin/ which gives me a 404 error.但是,我遇到的情况不是(2),而是(3) http://www.example.com//admin/ ,这给了我一个 404 错误。

Is this correct behaviour?这是正确的行为吗? What would be one way to resolve the 404 error?解决 404 错误的一种方法是什么? Thanks a lot.非常感谢。

Note: I am running on Django 1.3 + nginx + gunicorn.注意:我在 Django 1.3 + nginx + gunicorn 上运行。 I've tried running with Django 1.3 + nginx + apache + mod_wsgi and I'm getting (3) as well (so it's not a webserver problem) but I don't get the 404 error.我试过用 Django 1.3 + nginx + apache + mod_wsgi 运行,我也得到(3)(所以它不是 webserver04 错误)(所以它不是 webserver04 问题)。

====================================================================== ==================================================== =====================

UPDATE:更新:

The problem is with the nginx configuration, which I wrote to redirect HTTP requests to HTTPS.问题在于 nginx 配置,我编写该配置以将 HTTP 请求重定向到 HTTPS。 The following is a sample of the nginx configuration with the error:以下是错误的 nginx 配置示例:

upstream django {
    server 127.0.0.1:8000;
}

server {
    listen  80; 
    server_name www.example.com;

    location / { 
        rewrite (.*) https://www.example.com/$1 permanent;
    }   
}

server {
    listen       443;
    server_name  www.example.com;

    ssl                  on;
    ssl_certificate      /home/user/certs/example.com.chained.crt;
    ssl_certificate_key  /home/user/certs/example.com.key;
    ssl_prefer_server_ciphers on;

    ssl_session_timeout  5m;

    location ~ ^/static/(.*)$ {
        alias /home/user/deploy/static/$1;
        access_log off;
        expires max;
    }

    location / {
        try_files $uri $uri/ @django_proxy;
    }

    location @django_proxy {
        proxy_pass          http://django;
        proxy_redirect      off;    
        proxy_set_header    Host                 $host;          
        proxy_set_header    X-Real-IP            $remote_addr;   
        proxy_set_header    X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Protocol    https;  
    }
}

What was happening was the CommonMiddleware was redirecting from https://www.example.com/admin to http ://www.example.com/admin/.发生的事情是 CommonMiddleware 从https://www.example.com/admin重定向到http ://www.example.com/admin/。 This hit nginx again, and a URL rewrite was done as specified in the config file to https://www.example.com/ $1 where $1 is "/admin/".这再次击中 nginx,并按照配置文件中指定的https://www.example.com/$1进行了 URL 重写。 This meant that the final URL was https://www.example.com//admin/ .这意味着最终的 URL 是https://www.example.com//admin/

To correct this, I changed the rewrite rule to:为了纠正这个问题,我将重写规则更改为:

server {
    listen  80; 
    server_name www.example.com;

    location / { 
        rewrite /(.*) https://www.example.com/$1 permanent;
    }   
}

"Is this correct behavior?" “这是正确的行为吗?” No, it's not.不,这不对。 In 4 years of Djangoing I've never seen this particular problem.在 Djangoing 的 4 年中,我从未见过这个特殊问题。

One way of testing that the CommonMiddleware is causing this is to comment it out in your settings.py file, restart, and then see if you get the same behavior.测试 CommonMiddleware 是否导致此问题的一种方法是在您的settings.py文件中将其注释掉,重新启动,然后查看是否得到相同的行为。 It can also be instructive to use the standalone development server and stick print 's in interesting places to see who is mangling it.使用独立的开发服务器并在有趣的地方粘贴print以查看谁在破坏它也很有启发性。

Check your URL's.检查您的网址。 You most likely have defined your URL's a bit incorrectly.您很可能定义了您的 URL 有点不正确。 If you have如果你有

(r'^admin', include(admin.site.urls))

instead of the correct而不是正确的

(r'^admin/', include(admin.site.urls)),

You will see this type of 404 with the middleware您将看到带有中间件的这种类型的 404

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM