【问题标题】:What is the proper way to have a django 1.10 API serve static HTML content in DEBUG?让 django 1.10 API 在 DEBUG 中提供静态 HTML 内容的正确方法是什么?
【发布时间】:2017-03-30 21:39:14
【问题描述】:

我正在尝试构建一个简单的单页 Web 应用程序,其中 Web 服务器只提供静态内容,除非路由以“/api”开头 - 在这种情况下,请求被路由到 django。

文件结构如下:

ROOT - manage.py - static/ (static content) - index.html - app.min.js - ...etc - djangoapp/ (django "project") - __init__.py - settings.py - urls.py - wsgi.py - api/ (django "app") - __init__.py - admin.py - apps.py - models.py - tests.py - views.py

在开发中 (DEBUG=true),我希望 django 像传统的 Web 服务器一样提供静态内容。这意味着不在 /api 下的内容应该只从 /static 提供,并且'/' 的 GET 应返回 index.html。

我已采取以下步骤:

  1. django-admin startproject djangoapp创建了根django“项目”
  2. ./manage.py startapp api创建了一个django“应用程序”
  3. 创建了一个静态文件夹,其中包含一个虚拟 index.htmldummy.html
  4. 更改了 django“应用程序”,在 /api/hello 创建了一个简单的“hello I am the api”端点,并创建了适当的路由

从这一点开始,我可以成功地设置一个 docker-compose 集群以按预期执行 - 调用 nginx edge for '/' 加载 ROOT/static/index.html 中的静态 index.html,调用 '/ api/hello' 被代理到 uwgi 服务器并相应地返回。但是,我一辈子都无法让 django 从它的 ./manage.py runserver

中执行此操作

我很快从 Django 自己那里找到了执行此操作的指南:https://docs.djangoproject.com/en/1.10/howto/static-files/

但是,该文档中列出的建议都没有真正起作用。

设置

  • 'STATIC_URL' 到 '/'
  • 'STATIC_ROOT' 通过os.path.join(BASE_DIR, "static") 到项目的磁盘物理根目录

...不会以任何方式改变行为 - 对像 GET /dummy.html 这样的静态页面的请求不会路由

同时更改项目的 urls.py 以包含...的结果

django.conf.urls.static.static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

...也不会以任何方式改变行为。仅 404 秒。

我发现通过省略 STATIC_ROOT 值并将 STATICFILES_DIRS 值设置为磁盘上的物理文档根目录可以成功地提供静态文件 - 但会破坏所有其他端点(它们会抛出 404)。

环境:

  • Debian jessie(稳定版)
  • python 2.7.13(通过 pyenv 安装)
  • django 1.10.6(通过 pip 安装)

【问题讨论】:

标签: python django python-2.7


【解决方案1】:

核心问题似乎围绕着默认的 INSTALLED_APP 条目,django.contrib.staticfiles。在 settings.py 中禁用它是解决方案。


逐步说明构建“仅/api”django 1.10,它将在 DEBUG 模式下提供静态内容。

  1. 已安装 python 2.7/3.5+ 和 django。
  2. django-admin startproject PROJECTNAME创建一个新的django项目
  3. cd 进入 PROJECTNAME,使用./manage.py startapp api 创建 API “app”
  4. 使用 mkdir static 创建一个 staticfiles 文件夹,并使用您的转译/捆绑的网络客户端填充它。
  5. 打开 PROJECTNAME/settings.py,并更改以下设置:
    • 从 INSTALLED_APPS 数组中删除一个条目:django.contrib.staticfiles
    • 在 TEMPLATES.DIRS 数组中添加一个条目:os.path.join(BASE_DIR, "static")
    • 将 STATIC_URL 更改为 STATIC_URL = '/'
    • 将 STATIC_ROOT 更改为 STATIC_ROOT = os.path.join(BASE_DIR, "static")
  6. 按照以下步骤路由您的 api 应用的端点

在 'api/views.py' 中创建一个概念验证 API 端点,如下所示

from django.http import HttpResponse


def hello(request):
    return HttpResponse('{"response":"Hello. I am the API!"}', "application/json")

...并在 api/urls.py 中设置您的 api 应用程序的内部路由,如下所示:

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^hello$', views.hello, name='hello'),
]

通过编辑 PROJECTNAME/urls.py 将您的 api 应用程序添加到项目的 url 结构中,如下所示:

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^api/', include('api.urls')),
    url(r'^admin/', admin.site.urls),
]
  1. 通过如下更改 PROJECTNAME/urls.py 为静态内容添加仅 DEBUG 路由:
import os
from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin

urlpatterns = [
    url(r'^api/', include('api.urls')),
    url(r'^admin/', admin.site.urls),
]

if settings.DEBUG:
    from django.views.generic.base import TemplateView
    urlpatterns += [url(r'^$', TemplateView.as_view(template_name='index.html'))]

    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT, show_indexes=True)

...您现在应该能够使用manage.py runserver 在“开发模式”下运行您的 django 站点,并让 django 为您的静态内容提供服务。在生产中 (DEBUG != True),不会提供任何内容 - 因为它应该由专门提供静态内容的 Web 服务器处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-14
    • 2010-10-05
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    • 2012-11-27
    • 1970-01-01
    • 2014-07-09
    相关资源
    最近更新 更多