我已将Django项目部署在服务器上的子目录中(dns_name_of_my_page/notes).我可以通过dns_name_of_my_page/notes/app /访问此项目中的应用.不幸的是,如果整个Django项目位于托管服务器上的public_html中的子目录'notes'中,则admin站点无效.当我进入管理站点(dns_name_of_my_page/notes/admin /)时,重定向到URL而没有子目录的名称(dns_name_of_my_page/adminlogin /?next = // admin /),这是不可接受的.它应该是dns_name_of_my_page/notes/adminlogin /?next =/notes/admin /
这是我在项目中的URL配置:
urlpatterns = [
url(r'^/?app/?', include('app.urls')),
url(r'^/?$', views.index, name='index'),
url(r'^/?admin/?', admin.site.urls),
]
Run Code Online (Sandbox Code Playgroud)
以下是我的应用中的网址配置:
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^(?P<num>[0-9]+)/?', views.num, name='num'),
]
Run Code Online (Sandbox Code Playgroud)
我试过设置
FORCE_SCRIPT_NAME = '/notes/'
Run Code Online (Sandbox Code Playgroud)
要么
SUB_SITE = "/notes/"
Run Code Online (Sandbox Code Playgroud)
在settings.py但它没有帮助我.
你有没有在子目录中运行Django应用程序的这种问题?
今天我发现了这个问题,虽然有很多类似的问题 [1],但答案在某种程度上是我解决这个问题的经验的混合体。
您的问题中缺少的一个细节是您正在使用什么服务器设置。为了解释我的解决方案,它有助于理解它如何与 Django 方面结合使用。
我一直在解决的问题(包括访问 Django 的管理(以及大多数其他应用程序,例如 Auth))的问题是让一台服务器充当多个独立 django 项目的主机。目的是使 URI 以http://my.server.com/project_name/foo/bar/[2] 开头。就每个项目而言,它在 my.server.com 上运行,并且仅处理 /foo/bar (大多数生产/单应用程序系统以及使用 manage.py runserver 进行本地开发都是这种情况)
我使用 NGinx 作为反向代理,监听我的域的端口 80 和 443。在该服务器中,我有一个location设置来代理每个子项目的 Nginx 服务 + Gunicorn。
nginx 默认位置配置如下所示:
location /project_name {
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://localhost:7001/;
}
Run Code Online (Sandbox Code Playgroud)
每个项目自己的 nginx+gunicorn 服务的设置与本主题并不特别相关,但正如您所看到的,它出现在自己的本地服务端口上。
此配置将提供对http://my.server.com/foo/bar/. 现在,我们可以说服 Django 将 /project_name/ 前缀添加到它在输出中生成的所有 URL 中。
为此,您需要了解一些关键设置,这些是:
USE_X_FORWARDED_HOST = True
FORCE_SCRIPT_NAME = '/project_name/'
Run Code Online (Sandbox Code Playgroud)
这会导致 Django 尊重 nginx 传递的标头更改,并且还会触发它自己的进程来重写{% url name %}模板中标签的输出。
SESSION_COOKIE_PATH = '/project_name/'
Run Code Online (Sandbox Code Playgroud)
这应该有助于区分该域上的多个登录,并且意味着您可以登录一个项目,但不能登录另一个项目(或将其混淆)。
STATIC_FILES_ROOT='\path\on\disk\as\in\your\nginx\config\for\static\'
STATIC_FILES_URL='/project_name/static/'
MEDIA_FILES_ROOT='\path\on\disk\as\in\your\nginx\config\for\media\'
MEDIA_FILES_URL='/project_name/media/'
Run Code Online (Sandbox Code Playgroud)
它们处理“{% static blah %}”类型模板标签和文件服务。
LOGIN_REDIRECT_URL='/project_name/'
LOGOUT_REDIRECT_URL='/project_name/'
Run Code Online (Sandbox Code Playgroud)
它们处理使用 Auth 模块登录/退出服务的结果,并确保在登录或注销时将用户发送回项目站点的根目录。您可以轻松地根据自己的需要定制这些内容,包括使用 url-conf 样式的正则表达式字符串,例如我们将在下面的管理页面中执行的操作
ADMIN_URL=r'^admin/'
Run Code Online (Sandbox Code Playgroud)
此设置与站点 urls.py 中的这一行配对:
url(settings.ADMIN_URL, include(admin.site.urls)), # default=r'^admin/'
Run Code Online (Sandbox Code Playgroud)
这里的一个关键细节是正则表达式上没有前面的 / ,否则它会尝试强制返回主机名,因此 FORCE_SCRIPT_NAME 指定的更改将起作用。
另外,请注意模板中不要有任何以 / 开头的硬编码 URL(相对或其他),因为 Django 模板输出更改不会捕获这些 URL。
按照这种方法,我已经能够将这些项目中的每一个部署在三个不同的系统中,其中两个系统涉及它们作为该域或服务端口上唯一的 django 应用程序运行,其余一个是此共享域设置,并且不需要除了更改每个位置上的设置值之外的任何操作。
在您自己的代码示例中采用这种方法,我建议您寻求以下更改:
urlpatterns = [
url(r'^admin/?', admin.site.urls),
url(r'^app/?', include('app.urls')),
url(r'^$', views.index, name='index'),
]
Run Code Online (Sandbox Code Playgroud)
为了帮助搜索和匹配顺序,我重新安排了 admin 放在第一位,将空/home/root 匹配模板放在最后。否则,您的 FORCE_SCRIPT_NAME 设置是正确的。
[1] 例如,单个域上的多个 django 实例;是否可以在同一个域下托管多个 django 项目?; 如何在nginx后面的子url下部署django
[2] 默认服务器实际上也在处理 SSL 转换,因为服务是在 https 上提供的,但在内部本地主机端口(隐藏在计算机防火墙后面)仅处理 http。
| 归档时间: |
|
| 查看次数: |
776 次 |
| 最近记录: |