【问题标题】:Django serve static index.html with view at '/' urlDjango 在 '/' url 处提供静态 index.html 和视图
【发布时间】:2013-08-02 02:20:47
【问题描述】:

我的 index.html 在 /static/ 文件夹中。当我尝试时,我的 django 应用程序运行正常:

http://127.0.0.1:8000/index.html

但我想通过 url 访问 index.html:

http://127.0.0.1:8000/

我写了一个视图,它可以工作:

class IndexView(TemplateView):
    template_name = 'index.html'

我还添加到 urls.py(这让我可以像 http://127.0.0.1:8000/css/style.css 一样提供静态服务):

url(r'^(?P<path>.*)$', 'django.contrib.staticfiles.views.serve', {
            'document_root': settings.STATIC_ROOT, 'show_indexes':True
        }),

但我认为有一种方法可以在没有 TemplateView 的情况下做我想做的事。

有什么建议吗?谢谢。我的 django 版本是:Django 1.5

编辑

我将 index.html 放入 static 的原因:我想让 Phonegap 兼容 django 应用程序,所以在正确编码后,我所要做的就是 --> ma​​ke .zip from static 文件夹和将其作为移动应用程序上传到 Phonegap。简单干净。

【问题讨论】:

  • 你为什么不想要一个 TemplateView?就是因为这个原因。
  • 我只是觉得有一种方法可以在没有视野的情况下服务。
  • 然后使用flatpage app
  • 它是静态 html,而不是模板。没有 django tempalte 标签等的静态代码和平。
  • 好的,也许下次我会使用它。将另一个应用程序包含到 django 中并没有更糟糕的页面服务。

标签: django django-views django-staticfiles


【解决方案1】:

您可以像这样为static/index.html 提供服务:

if settings.DEBUG:
    urlpatterns += url(
        r'^$', 'django.contrib.staticfiles.views.serve', kwargs={
            'path': 'index.html', 'document_root': settings.STATIC_ROOT}),

但对于生产,您应该配置您的 nginx(或其他前端服务器)为 index.html 位置提供 index.html 文件

更新

我想解释一下你应该这样做的情况。例如,您的 django 应用程序只是 admin 和 api 视图,但客户端与单页应用程序(Ember、Angular 等)交互。所以你的项目至少有两个子项目,一个是你的主要 django 应用程序,第二个是一个包含所有 html/js/css 内容的客户端应用程序。将客户端脚本与 django 后端分开非常方便,它允许您的前端开发人员完成他们的工作并避免 django 的存在(有一天它可以移动到不同的 repo)。

因此,在这种情况下,您将获得以下构建工作流程:

  1. 运行客户端应用程序源观察器以重建您的脚本/样式/模板(brunch watchgrunt 作业或gulp 观察任务)
  2. 使用 django 收集静态以用于生产
  3. 确保您已为开发修复了 urlpatterns 并为生产提供了正确的 nginx 配置

这是我的urls.py 示例

urlpatterns += patterns(
    'django.contrib.staticfiles.views',
    url(r'^(?:index.html)?$', 'serve', kwargs={'path': 'index.html'}),
    url(r'^(?P<path>(?:js|css|img)/.*)$', 'serve'),
)

【讨论】:

  • 谢谢。您如何处理 HTML5 History API 并从 src 文件夹提供服务?我构建了我的 Angular 应用程序,以便在开发期间从 src 提供它们。我修改了模式,以便 index.html 被捕获所有 URL 模式捕获,并将其放在资产模式之前。似乎工作。但我想从模板/src 提供 js/css/img。尝试更改文档。 root 但它不起作用(无法将代码粘贴到回复中)
  • @Howie 是开源项目吗?你能告诉我你有什么吗?
  • 嗨@Anton。抱歉迟了回应。我在 Github 上创建了一个样板来使用您上面的建议。也许你可以提供一个提示? SPA 在 Django 之外工作,但不通过 Django github.com/howieweiner/django-angular-boilerplate 提供服务。谢谢
  • 来自 Django 文档 警告 此视图仅在 DEBUG 为 True 时有效。那是因为这种观点非常低效并且可能不安全。这仅用于本地开发,绝不能用于生产。
【解决方案2】:

在这种情况下,您不需要继承 TemplateView。你可以直接在你的 url conf 中使用TemplateView,只要index.html 在你的模板目录中。

from django.views.generic.base import TemplateView

urlpatterns = [
    url(r'^$', TemplateView.as_view(template_name='index.html'), name="home"),
]

【讨论】:

  • views.serve 助手仅用于开发。您不应该使用 Django 在生产环境中提供静态文件。使用您的网络服务器,例如Apache 或 Nginx 提供静态文件。
  • @Alasdair 你能解释一下为什么不吗?我的意思是每个人都这么说,但他们从不说为什么。如果您正在为一个 SPA 提供服务,该 SPA 在一个预编译的有效负载中提供其整个视图设备,那么让 Django 提供服务似乎并没有那么糟糕。任何给定的访问者只会加载一次。但如果有一些不早于现代 SPA 架构的原因,我很想知道它们是什么。
  • @npskirk 在生产中不使用它的主要原因是安全性,而不是效率。 warning in the Django docs 非常明确。
  • 别忘了加from django.views.generic import TemplateView
  • @Feuermurmel 如果设置了正确的缓存标头,客户端可以缓存资源。页面是由 Django 还是其他 Web 服务器提供的并不重要。
【解决方案3】:

查看我对如何在/ 上以this answer(或扩展为blog post)提供index.html 的详细说明。但是,如果您想拥有一个由 Django 提供的成熟 SPA(因为您需要前端路由),那么仅此解决方案可能还不够。

我一直在使用不同的方法将/static/ 路由到/,将所有请求转发到前端,查找 index.html 文件。最后,我发现解决所有这些问题的最佳方法不是通过调整 urls.py,而是作为我发布为 django-spa 的 WhiteNoise 的扩展(自述文件中的安装说明)。

你可以在这个WhiteNoise issue找到一些相关的讨论。

【讨论】:

    【解决方案4】:

    只需将静态 HTML 文件包装在模板化 HTML 文件中定义的 iframe 中即可。通过一些样式调整可以使 iframe 的宽度和高度达到 100%。

    {% load static %}
    <html>
        <head>
            <title>Templated HTML</title>
    
            <style>
                html, body {
                    width: 100%;
                    width: 100%;
                    margin: 0;
                    padding: 0;
                    border-width: 0;
                }
    
                iframe {
                    position: absolute;
                    top: 0;
                    left: 0;
                    width: 100vw;
                    height: 100vh;
                    margin: 0;
                    padding: 0;
                    border-width: 0;
                }
            </style>
        </head>
        <body>
            {{ content }}
            <iframe src="{% static 'main/html/test.html' %}"></iframe>
        </body>
    </html>
    

    【讨论】:

    • 嗨,让我们说数组名称 graph=['A.html','B.html'] 然后 {% for i in graph %} {% endfor %} 编辑 src 链接的任何想法,当我运行它时返回 发生服务器错误。请联系管理员。
    【解决方案5】:

    你可以创建模板目录,把html放在那里,然后从views.py渲染它

        def index(request):
            return render(request, 'my_app/index.html', context={})
    

    不要忘记在 settings.py 中设置 templates_dir

    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    TEMPLATES_DIR = os.path.join(BASE_DIR, "templates")
    
    TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [TEMPLATES_DIR,],
        'APP_DIRS': True,
        ...
    

    【讨论】:

      猜你喜欢
      • 2016-01-18
      • 2017-05-24
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 2017-02-21
      • 2012-08-02
      • 2014-07-25
      • 1970-01-01
      相关资源
      最近更新 更多