在 Django 中将不同的模板呈现为相同的 URL 模式

Posted

技术标签:

【中文标题】在 Django 中将不同的模板呈现为相同的 URL 模式【英文标题】:Rendering different templates to the same URL pattern in Django 【发布时间】:2017-10-16 15:06:04 【问题描述】:

我的问题类似于Same URL in multiple views in Django,但我不是根据user_authentication渲染模板,而是根据浏览器中启用或禁用javascript

我想做什么?

如果在浏览器中启用了 JavaScript,我将尝试呈现 index.html 页面,否则我想呈现 jsDisabled.html 页面,如果它被禁用并且两个页面都应该以相同的 URL 模式呈现,例如:

如果在浏览器中启用了 JavaScript,localhost:8000 应该呈现 index.html,如果 JavaScript 被禁用,它应该呈现 jsDisabled.html 页面。

注意:我正在使用 <noscript> 标记检查浏览器中是否禁用了 JavaScript,该标记将在禁用 JavaScript 时运行。

到目前为止,这是我的代码:

base.html:

% load staticfiles %

<!DOCTYPE html>
<html>
    <head>
    </head>

    <body class="noJs">
        ...
        <a href="% url 'index' 0 %"> abc </a>
        ...
        <noscript>
            <style type="text/css">
                .noJs 
                    display: none;
                
            </style>
            <meta http-equiv="refresh" content="% ulr 'index' 1 %"> /* This should render jsDisabled.html page on the same URL which is 'localhost:8000' */

        </noscript>
    </body>
</html>

urls.py:

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

urlpatterns = [
  ...
  url(r'^(?P<flag>[0-1])$', views.index, name='index'),
]

views.py:

from django.shortcuts import render

def index(request, flag):
    if (flag):
       return render(request, 'jsDisabled.html')
    else:
       return render(request, 'index.html')

【问题讨论】:

你怎么知道js被禁用了?浏览器不会宣布这个事实。 &lt;noscript&gt; 标签会告诉你。看看我的 base.html 代码。 【参考方案1】:

根据您的 Django 版本,您可能需要在 settings.py 中指定 TEMPLATE_DIR =(在较新的版本中,这不是必需的)。

这里有一些关于模板和标签逻辑的有用 information:

Main/templates/myapp/base.html
Main/templates/myapp/index.html
Main/templates/myapp/includes/yes_js.html
Main/templates/myapp/includes/no_js.html

base.html:

% load staticfiles %

<!DOCTYPE html>
<html>
<head>
</head>
<body>
% block content %
% endblock %
</body>
</html>

index.html:

% extends 'myapp/base.html' %
% load staticfiles %

% block content %
<noscript>
% include 'no_js.html' %
</noscript>

% include 'yes_js.html' %

% endblock %

【讨论】:

首先非常感谢您的回答,其次什么是“输出 ”?我不必在这里检查条件,因为 那是假设您的测试逻辑的伪代码。我不认为你想同时包含 no_js 和 yes_js,你仍然需要运行你的测试用例,但这允许你在前端运行逻辑并且只包含需要的 html。 更新的解决方案。如果没有测试用例,只需在 % include 'jsDisabled.html' % 抛出一个错误,我在文档上看到了它,但我没有得到它。我想在我的 base.html 中呈现 jsDisabled.html,因为我的 base.html 包含用于显示页面页眉和页脚的代码,如果我尝试在 index.html 中显示 jsDisabled.html,它将显示页眉和页脚以及我不想要的。 % include 'file.html' % 从 main/templates/myapp/includes/file.html 检查并确保目录路径准确。我喜欢在全球范围内为标准页眉和页脚以及脚本信息提供 base.html。使用 % extends 'myapp/base.html' % 然后创建包含内容来填充这些模板的 index.html。【参考方案2】:

经过大量调试,我终于找到了解决方案:) 这里是:

base.html:

% load staticfiles %

<!DOCTYPE html>
<html>
<head>
</head>
<body>
 <div class="noJs">
    ...
    <a href="% url 'index' 0 %"> abc </a>
    ...
 </div>
 <noscript>
    <style type="text/css">
        .noJs 

            display: none;
       
    </style>
    % include 'includes/jsDisabled.html' %
</noscript>
</body>
</html>

urls.py

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

urlpatterns = [

   url(r'^admin/', admin.site.urls),
   url(r'^articles/', include('articles.urls')),
   url(r'^contact/', include('contact.urls')),
   url(r'^temp/',views.temp, name="temp"),
   url(r'^$', views.index, name='index'),
]

views.py:

from django.shortcuts import render

def index(request):
    return render(request,'index.html')

def temp(request):
     return render(request,'temp.html')

我通过在模板文件夹中创建一个名为includes 的文件夹并将jsDisabled.html 放入其中,将include 内置模板标签包含为@noes1s 建议的% include 'includes/jsDisabled.html' %

【讨论】:

以上是关于在 Django 中将不同的模板呈现为相同的 URL 模式的主要内容,如果未能解决你的问题,请参考以下文章

在 Google App Engine 中将 docx 文件呈现为 django 模板

Django为表单中的两个提交按钮呈现不同的模板

在 Django 模板中将卡片组划分为行的最佳方法 - Django

Django模板 - 来自media_root的图片在主页中呈现,但不是其他页面

如何将 django 模板变量呈现为 html?

在 Django 中将值传递给 Bootstrap 模式