Django 在 '/' url 处提供静态 index.html 和视图

Posted

技术标签:

【中文标题】Django 在 \'/\' url 处提供静态 index.html 和视图【英文标题】: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 中并没有更糟糕的页面服务。 【参考方案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)。

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

    运行客户端应用程序源观察器以重建您的脚本/样式/模板(brunch watchgrunt 作业或gulp 观察任务) 使用 django 收集静态以用于生产 确保您已为开发修复了 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,
    ...

【讨论】:

以上是关于Django 在 '/' url 处提供静态 index.html 和视图的主要内容,如果未能解决你的问题,请参考以下文章

使用 Django 静态 URL 版本控制的最简单方法?

django staticfiles 在 url 根

Django 1.7 - 提供静态文件

Django在配置STATIC_ROOT的情况下不提供静态文件服务。

从 S3 提供 Django 的静态和媒体文件

通过 django 提供静态文件时找不到页面