环境信息
使用方法 在 Django 4.1 中,使用静态文件的方法与之前的版本相同。以下是使用静态文件的步骤:
在 settings.py
中设置静态文件目录:
settings.py STATIC_URL = '/static/' STATICFILES_DIRS = [ BASE_DIR / "static" , ]
STATIC_URL
是静态文件 URL 的前缀。
STATICFILES_DIRS
是一个列表,其中包含要在其中查找静态文件的目录。
在 HTML 文件中使用静态文件
{% load static %} <!DOCTYPE html > <html > <head > <title > My Static File Example</title > <link rel ="stylesheet" type ="text/css" href ="{% static 'css/style.css' %}" > </head > <body > <img src ="{% static 'images/logo.png' %}" alt ="My logo" > <script src ="{% static 'js/script.js' %}" > </script > </body > </html >
在上面的示例中,我们使用了 Django 模板语言的 {% static %}
标记来引用静态文件。{% load static %}
指令必须在使用 {% static %}
标记之前加载,以确保 Django 能够正确解析它们。
运行 collectstatic
命令: 当您准备部署您的 Django 应用程序时,您需要将静态文件收集到一个单独的目录中,以便可以轻松地在生产服务器上提供它们。您可以使用 Django 的 collectstatic
命令来完成此操作。在命令行中运行以下命令:
python manage.py collectstatic
Django 将在 STATIC_ROOT
目录中创建一个新的静态文件目录,并将您的静态文件从 STATICFILES_DIRS
中指定的目录复制到该目录中。您可以在 settings.py
文件中设置 STATIC_ROOT
目录的路径
DTL 语法 load static 参考说明
block.super 用来从父 block 中继承选项
{% load static %} {% block extrahead %} {{ block.super }} <link href ="{% static 'bootstrap/css/bootstrap.css' %}" rel ="stylesheet" /> <link href ="{% static 'bootstrap/css/base.css' %}" rel ="stylesheet" /> {% endblock %}
include 假设有两个 HTML 文件:header.html
和 content.html
。header.html
包含页面的头部内容。
header.html <header > <h1 > My Website</h1 > <nav > </nav > </header >
content.html
包含页面的主要内容。
content.html <section > <h2 > Welcome to our website!</h2 > <p > This is the main content of the page.</p > </section >
现在,可以在另一个 HTML 文件中使用 {% include %}
标签来包含这些内容。
main_template.html <!DOCTYPE html > <html > <head > <title > My Website</title > </head > <body > {% include 'header.html' %} <div class ="content" > {% include 'content.html' %} </div > <footer > </footer > </body > </html >
在这个示例中,{% include 'header.html' %}
和 {% include 'content.html' %}
标签会将相应的模板文件的内容包含在 main_template.html
中。这样,就可以在一个模板中包含另一个模板的内容了。
url 反向解析 在模板中不推荐使用 url 硬编码,建议使用 url 反向解析功能,在 urls.py
中定义 url 时,给 url 命名,在模板中 可以使用反向解析使用 url,避免使用 url 硬编码。需要在 urls.py
中配置 app_name = 'polls'
,否则会因为 namespace 不清楚而报错:'polls' is not a registered namespace
from django.urls import pathfrom . import viewsapp_name = 'polls' urlpatterns = [ path('' , views.IndexView.as_view(), name='index' ), ]
以上事例中,name='index'
为 url 命名,在模板中通过以下方式使用 url 名称 [1]
<a href ="{% url 'polls:index' %}" > 首页</a >
for 循环 根据 model 中的值实现下拉选择菜单 假如需要实现下拉表单中的可选值来自于某个 model
,可以参考以下实现
models.py from django.db import models # Create your models here. class Account(models.Model): name = models.CharField(max_length=16, unique=True)
视图函数代码如下:
views.py from django.shortcuts import render from django.http import HttpResponse from django.contrib.auth.decorators import login_required from cloudclient import models # Create your views here. @login_required def index(request): accounts = models.Account.objects.all() return render(request, 'index.html', {'accounts': accounts})
HTML 模板主要代码如下:
index.html <form method ="POST" > {% csrf_token %} <label for ="category" > Select An Account: </label > <select name ="account" id ="account" > {% for account in accounts %} <option value ="{{ account.id }}" > {{ account.name }}</option > {% endfor %} </select > <button type ="submit" > Submit</button > </form >
其中使用 for
循环将视图函数传过来的参数列表(accounts
)中的对象添加到下拉菜单中作为下拉选项。
表单提交后,服务端口会收到 POST 的数据(request.POST
):account=1
。参考以下代码处理接收到的表单数据
views.py @login_required def index(request): if request.method == 'GET': accounts = models.Account.objects.all() return render(request, 'index.html', {'accounts': accounts}) if request.method == 'POST': # data = request.body account_id = request.POST.get('account') logging.info(f"POST DATA: {}")
如果想在 POST 处理后返回给客户端的 HTML 表单中的默认选中的值任然是客户端 POST 提交时选中的值,可以参考以下代码
views.py @login_required def cf_add_domains(request): accounts = models.Account.objects.all() if request.method == 'POST': data = request.POST account_id = data['account'] account = models.Account.objects.get(id=account_id) return render(request, 'index.html', {'accounts': accounts, 'selected_account_id': account_id})
HTML 模板中使用 option
的 selected
标签选择指定的值。要注意其中的类型转换 account.id|stringformat:"s" == selected_account_id|stringformat:"s",将变量值转换一致,否则条件判断会失败
index.html <form method ="POST" > {% csrf_token %} <label for ="account" > Select An Account: </label > <select name ="account" id ="account" > {% for account in accounts %} {% if account.id|stringformat:"s" == selected_account_id|stringformat:"s" %} <option value ="{{ account.id }}" selected > {{ account.name }}</option > {% else %} <option value ="{{ account.id }}" > {{ account.name }}-{{ account.id }}-{{ selected_account_id }}</option > {% endif %} {% endfor %} </select > <button type ="submit" > Submit</button > </form >
if 条件判断 if
语法如下
{% if condition %} {% else %} {% endif %} {% if user.is_authenticated %} <p > 欢迎回来,{{ user.username }}!</p > <a href ="{% url 'logout' %}" > 退出登录</a > {% else %} <p > 您还未登录。</p > <a href ="{% url 'login' %}" > 立即登录</a > {% endif %}
类型转换 如果在模板中需要对变量类型进行转换,参考以下语法
{% for account in accounts %} {% if account.id|stringformat:"s" == selected_account_id|stringformat:"s" %} <option value ="{{ account.id }}" selected > {{ account.name }}</option > {% else %} <option value ="{{ account.id }}" > {{ account.name }}-{{ account.id }}-{{ selected_account_id }}</option > {% endif %} {% endfor %}
更精简的写法
{% for account in accounts %} <option value ="{{ account.id }}" {% if account.id |stringformat: "s " == selected_account_id|stringformat: "s " %}selected {% endif %}> {{ account.name }}</option > {% endfor %}
脚注