接上回
四、Django 模板标签
4.过滤器
safe标签
这里介绍一个safe
将字符串标记为安全,不需要转义。
要保证 views.py 传过来的数据绝对安全,才能用 safe。
Django 会自动对 views.py 传到HTML文件中的标签语法进行转义,令其语义失效。加 safe 过滤器是告诉 Django 该数据是安全的,不必对其进行转义,可以让该数据语义生效。
vs.py代码如下(从views.py改名):
from django.shortcuts import render
def runoob(request):
views_str = "<a href='https://www.runoob.com/'>点击跳转</a>"
return render(request, "runoob.html", {"views_str": views_str})
runoob.html:
runoob文件作为模板文件的设置方式是settings中的TEMPLATES的Dirs修改为
'Dirs': [os.path.join(BASE_DIR, 'templates')],
<!DOCTYPE html>
<html lang="en">
<head>
<Meta charset="UTF-8">
<title>这里是标题</title>
</head>
<body>
这里是正文
<!--<h1>{{ hello }}</h1>-->
{{ views_str|safe }}
</body>
</html>
urls.py依旧不变:
from django.urls import path
from . import vs
urlpatterns = [
path('runoob/', vs.runoob),
]
运行结果如下:
runoob.html文件中不加safe过滤的结果运行如下:
if/else 标签
基本语法格式如下:
{% if condition %}
... display
{% endif %}
或者:
{% if condition1 %}
... display 1
{% elif condition2 %}
... display 2
{% else %}
... display 3
{% endif %}
{% if %} 标签接受 and , or 或者 not 关键字来对多个变量做判断 ,或者对变量取反( not )
urls.py不变。
vs.py:
from django.shortcuts import render
def runoob(request):
#尝试hello world
# context = {}
# context['hello'] = 'Hello World!'
# return render(request, 'runoob.html', context)
#尝试safe标签
# views_str = "<a href='https://www.runoob.com/'>点击跳转</a>"
# return render(request, "runoob.html", {"views_str": views_str})
#尝试if/else标签
views_num = 88
return render(request, "runoob.html", {"num": views_num})
runoob.html:
<!DOCTYPE html>
<html lang="en">
<head>
<Meta charset="UTF-8">
<title>这里是标题</title>
</head>
<body>
这里是正文
<!--尝试hello world-->
<!--<h1>{{ hello }}</h1>-->
<!--尝试safe标签-->
<!--{{ views_str|safe}}-->
<!--尝试if/else标签-->
{%if num > 90 and num <= 100 %}
优秀
{% elif num > 60 and num <= 90 %}
合格
{% else %}
一边玩去~
{% endif %}
</body>
</html>
运行结果:
for标签
{% for %} 允许我们在一个序列上迭代。
与 Python 的 for 语句的情形类似,循环语法是 for X in Y ,Y 是要迭代的序列而 X 是在每一个特定的循环中使用的变量名称。
每一次循环中,模板系统会渲染在 {% for %} 和 {% endfor %} 之间的所有内容。
例如,给定一个运动员列表 athlete_list 变量,我们可以使用下面的代码来显示这个列表:
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
runoob.html:
<body>
这里是正文
<!--尝试hello world-->
<!--<h1>{{ hello }}</h1>-->
<!--尝试safe标签-->
<!--{{ views_str|safe}}-->
<!--尝试if/else标签-->
<!--{%if num > 90 and num <= 100 %}-->
<!--优秀-->
<!--{% elif num > 60 and num <= 90 %}-->
<!--合格-->
<!--{% else %}-->
<!--一边玩去~-->
<!--{% endif %}-->
<!--for标签-->
{% for i in views_list %}
{{ i }}
{% endfor %}
</body>
vs.py:
def runoob(request):
#尝试hello world
# context = {}
# context['hello'] = 'Hello World!'
# return render(request, 'runoob.html', context)
#尝试safe标签
# views_str = "<a href='https://www.runoob.com/'>点击跳转</a>"
# return render(request, "runoob.html", {"views_str": views_str})
#尝试if/else标签
# views_num = 88
# return render(request, "runoob.html", {"num": views_num})
#for标签
views_list = ["菜鸟教程","菜鸟教程1","菜鸟教程2","菜鸟教程3",]
return render(request, "runoob.html", {"views_list": views_list})
运行结果:
给标签增加一个 reversed 使得该列表被反向迭代:
runoob.html:
{% for i in views_list reversed%}
{{ i }}
{% endfor %}
结果:
遍历字典:
可以直接用字典 .items 方法,用变量的解包分别获取键和值。
vs.py:
#遍历字典
views_dict = {"name": "菜鸟教程", "age": 18}
return render(request, "runoob.html", {"views_dict": views_dict})
runoob.html:
<!--遍历字典-->
{% for i,j in views_dict.items %}
{{ i }}---{{ j }}
{% endfor %}
结果:
{% empty %}
可选的 {% empty %} 从句:在循环为空的时候执行(即 in 后面的参数布尔值为 False )。
runoob.html:
{% for i in listvar %}
{{ forloop.counter0 }}
{% empty %}
空空如也~
{% endfor %}
vs.py
#empty
views_list = []
return render(request, "runoob.html", {"listvar": views_list})
结果:
注释标签
Django 注释使用 {# #}。
{# 这是一个注释 #}
include 标签
{% include %} 标签允许在模板中包含其它的模板的内容。
下面这个例子都包含了 nav.html 模板:
{% include "nav.html" %}
五、Django模型
1.数据库配置
Django 如何使用 MysqL 数据库
先在Pycharm中下载MysqL
Django 模型使用自带的 ORM。 对象关系映射(Object Relational Mapping,简称 ORM
)用于实现面向对象编程语言里不同类型系统的数据之间的转换。
电脑本地下载MysqL,创建一个名为runoob的数据库。
创建 MysqL 数据库( ORM 无法操作到数据库级别,只能操作到数据表)语法:
create database 数据库名称 default charset=utf8; # 防止编码问题,指定为 utf8
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
修改后:
DATABASES = {
'default':
{
'ENGINE': 'django.db.backends.MysqL', # 数据库引擎
'NAME': 'runoob', # 数据库名称
'HOST': '127.0.0.1', # 数据库地址,本机 ip 地址 127.0.0.1
'PORT': 3306, # 端口
'USER': 'root', # 数据库用户名
'PASSWORD': '123456', # 数据库密码
}
}
告诉 Django 使用 pyMysqL 模块连接 MysqL 数据库:
# 在与 settings.py 同级目录下的 __init__.py 中引入模块和进行配置
import pyMysqL
pyMysqL.install_as_MysqLdb()
2.定义模型
我们之前已经在终端中使用django-admin startapp app01
命令新建了一个应用app01,现在的目录结构如下:
我们修改 app01/models.py 文件,代码如下:
# models.py
from django.db import models
class Test(models.Model):
name = models.CharField(max_length=20)
以上的类名代表了数据库表名,且继承了models.Model,类里面的字段代表数据表中的字段(name),数据类型则由CharField(相当于varchar)、DateField(相当于datetime), max_length 参数限定长度。
接下来在myapp/settings.py 中找到INSTALLED_APPS这一项,如下:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01', #添加此项
]
在Pycharm中终端中进入myapp目录下依次执行以下命令:
manage.py migrate # 创建表结构
manage.py makemigrations TestModel # 让 Django 知道我们在我们的模型有一些变更
manage.py migrate TestModel # 创建表结构
我们的文档结构变成了这样:
3.数据库操作
myapp/myapp目录中添加 testdb.py 文件(下面介绍),并修改 urls.py:
from django.urls import path
from . import vs
from . import testdb
urlpatterns = [
path('runoob/', vs.runoob),
path('testdb/',testdb.testdb)
]
后续的添加数据、修改数据、更新数据等数据库操作均只需改变testdb.py文件即可,urls.py文件不变。
添加数据
添加数据需要先创建对象,然后再执行 save 函数,相当于sql中的INSERT:
myapp/myapp/testdb.py: 文件代码:
from django.http import HttpResponse
from app01.models import Test
# 数据库操作
def testdb(request):
test1 = Test(name='runoob')
test1.save()
return HttpResponse("<p>数据添加成功!</p>")
访问http://127.0.0.1:8000/testdb/
获取数据:
myapp/myapp/testdb.py: 文件代码:
# 数据库操作,获取数据
def testdb(request):
# 初始化
response = ""
response1 = ""
# 通过objects这个模型管理器的all()获得所有数据行,相当于sql中的SELECT * FROM
list = Test.objects.all()
# filter相当于sql中的WHERE,可设置条件过滤结果
response2 = Test.objects.filter(id=1)
# 获取单个对象
response3 = Test.objects.get(id=1)
# 限制返回的数据 相当于 sql 中的 OFFSET 0 LIMIT 2;
Test.objects.order_by('name')[0:2]
# 数据排序
Test.objects.order_by("id")
# 上面的方法可以连锁使用
Test.objects.filter(name="runoob").order_by("id")
# 输出所有数据
for var in list:
response1 += var.name + " "
response = response1
return HttpResponse("<p>" + response + "</p>")
运行结果:
更新数据
myapp/myapp/testdb.py: 文件代码:
# 数据库操作,更新数据
def testdb(request):
# 修改其中一个id=1的name字段,再save,相当于sql中的UPDATE
test1 = Test.objects.get(id=1)
test1.name = 'Google'
test1.save()
# 另外一种方式
# Test.objects.filter(id=1).update(name='Google')
# 修改所有的列
# Test.objects.all().update(name='Google')
return HttpResponse("<p>修改成功</p>")
运行结果:
当我下载navicat之后显示如下:
删除数据
myapp/myapp/testdb.py: 文件代码:
# 数据库操作,删除数据
def testdb(request):
# 删除id=1的数据
test1 = Test.objects.get(id=1)
test1.delete()
# 另外一种方式
# Test.objects.filter(id=1).delete()
# 删除所有数据
# Test.objects.all().delete()
return HttpResponse("<p>删除成功</p>")
运行结果:
navicat显示:
汇总:
此刻目录结构:
myapp.myapp.init.py
# 在与 settings.py 同级目录下的 __init__.py 中引入模块和进行配置
import pyMysqL
pyMysqL.install_as_MysqLdb()
myapp.myapp.urls.py
'''
from django.urls import re_path as url
from . import vs
urlpatterns = [
url(r'^$', vs.hello),
]
'''
#数据库操作修改前
# from django.urls import path
# from . import vs
# urlpatterns = [
# path('runoob/', vs.runoob),
# ]
#数据库操作修改后
from django.urls import path
from . import vs
from . import testdb
urlpatterns = [
path('runoob/', vs.runoob),
path('testdb/',testdb.testdb)
]
myapp.myapp.vs.py
from django.shortcuts import render
def runoob(request):
#尝试hello world
# context = {}
# context['hello'] = 'Hello World!'
# return render(request, 'runoob.html', context)
#尝试safe标签
# views_str = "<a href='https://www.runoob.com/'>点击跳转</a>"
# return render(request, "runoob.html", {"views_str": views_str})
#尝试if/else标签
# views_num = 88
# return render(request, "runoob.html", {"num": views_num})
#for标签
# views_list = ["菜鸟教程","菜鸟教程1","菜鸟教程2","菜鸟教程3",]
# return render(request, "runoob.html", {"views_list": views_list})
#遍历字典
# views_dict = {"name": "菜鸟教程", "age": 18}
# return render(request, "runoob.html", {"views_dict": views_dict})
#empty
views_list = []
return render(request, "runoob.html", {"listvar": views_list})
myapp.myapp.testdb.py
# -*- coding: utf-8 -*-
#
# from django.http import HttpResponse
#
# from myapp.app01.models import Test
#
#
# # 数据库操作
# def testdb(request):
# # 初始化
# response = ""
# response1 = ""
#
# # 通过objects这个模型管理器的all()获得所有数据行,相当于sql中的SELECT * FROM
# list = Test.objects.all()
#
# # filter相当于sql中的WHERE,可设置条件过滤结果
# response2 = Test.objects.filter(id=1)
#
# # 获取单个对象
# response3 = Test.objects.get(id=1)
#
# # 限制返回的数据 相当于 sql 中的 OFFSET 0 LIMIT 2;
# Test.objects.order_by('name')[0:2]
#
# # 数据排序
# Test.objects.order_by("id")
#
# # 上面的方法可以连锁使用
# Test.objects.filter(name="runoob").order_by("id")
#
# # 输出所有数据
# for var in list:
# response1 += var.name + " "
# response = response1
# return HttpResponse("<p>" + response + "</p>")
# -*- coding: utf-8 -*-
from django.http import HttpResponse
# from myapp.app01.models import Test
# 数据库操作
# from app01.models import Test
from app01.models import Test
#添加数据
# def testdb(request):
# test1 = Test(name='runoob')
# test1.save()
# return HttpResponse("<p>数据添加成功!</p>")
# 数据库操作,获取数据
# def testdb(request):
# # 初始化
# response = ""
# response1 = ""
#
# # 通过objects这个模型管理器的all()获得所有数据行,相当于sql中的SELECT * FROM
# list = Test.objects.all()
#
# # filter相当于sql中的WHERE,可设置条件过滤结果
# response2 = Test.objects.filter(id=1)
#
# # 获取单个对象
# response3 = Test.objects.get(id=1)
#
# # 限制返回的数据 相当于 sql 中的 OFFSET 0 LIMIT 2;
# Test.objects.order_by('name')[0:2]
#
# # 数据排序
# Test.objects.order_by("id")
#
# # 上面的方法可以连锁使用
# Test.objects.filter(name="runoob").order_by("id")
#
# # 输出所有数据
# for var in list:
# response1 += var.name + " "
# response = response1
# return HttpResponse("<p>" + response + "</p>")
# 数据库操作,更新数据
# def testdb(request):
# # 修改其中一个id=1的name字段,再save,相当于sql中的UPDATE
# test1 = Test.objects.get(id=1)
# test1.name = 'Google'
# test1.save()
#
# # 另外一种方式
# # Test.objects.filter(id=1).update(name='Google')
#
# # 修改所有的列
# # Test.objects.all().update(name='Google')
#
# return HttpResponse("<p>修改成功</p>")
# 数据库操作,删除数据
def testdb(request):
# 删除id=1的数据
test1 = Test.objects.get(id=1)
test1.delete()
# 另外一种方式
# Test.objects.filter(id=1).delete()
# 删除所有数据
# Test.objects.all().delete()
return HttpResponse("<p>删除成功</p>")
myapp.myapp.settings.py
# Application deFinition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01', #添加此项
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLconf = 'myapp.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'Dirs': [os.path.join(BASE_DIR, 'templates')],
'APP_Dirs': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
# "libraries":{ # 添加这边三行配置
# 'my_tags':'templatetags.my_tags' # 添加这边三行配置
# } # 添加这边三行配置
},
},
]
Wsgi_APPLICATION = 'myapp.wsgi.application'
#数据库修改前
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': BASE_DIR / 'db.sqlite3',
# }
# }
#数据库修改后
DATABASES = {
'default':
{
'ENGINE': 'django.db.backends.MysqL', # 数据库引擎
'NAME': 'runoob', # 数据库名称
'HOST': '127.0.0.1', # 数据库地址,本机 ip 地址 127.0.0.1
'PORT': 3306, # 端口
'USER': 'root', # 数据库用户名
'PASSWORD': '123456', # 数据库密码
}
}
myapp.app01.models.py
from django.db import models
# Create your models here.
# models.py
from django.db import models
class Test(models.Model):
name = models.CharField(max_length=20)