django基础(1)

记录转发于以山河作礼。的文章

什么是django?

django reinhardt(莱因哈特)吉他手命名,最初开发被用于管理劳伦斯集团旗下一些以新闻为主的网站。 是一套组件,提供通用的设计模式,能够最大程度降低web站点开发的难度,使复杂的工作简单化。

django —— 使用python语言开发的一款免费且开源的web框架

django框架提点

  • 因python语句具有跨平台的特性,django同样支持Windows、mac等系统。
  • 经多年发展与完善,django官方提供了较为完善的在线文档,为开发者提供问题支持。
  • django的model层自带数据库ORM组件,为操作不同类型的数据库提供统一方法。
  • django使用正则表单式管理URL映射,因此给开发者带来了极高的灵活性。
  • 开发者只需通过简单的几行代码就可以实现完整的后台数据管理web控制台。
  • 在开发调试过程中如出现异常,django可提供完整的错误信息帮助开发者定位问题。

django的设计模式

MVC设计模式
web设计的经典之作,MTV模式也是由此基础上衍生而来的。

MVC是Model-View-Controller(模型-视图-控制器)的缩写,主要应用于web应用的开发。其中,model表示数据和业务逻辑,View表示用户界面,Controller则负责处理用户请求、更新model和view以及路由控制等一系列操作。通常来说,MVC会将controller和view分开,使得系统的拓展性和可维护下更高。
MVC —— Model-View-Controller缩写,其中:

  • Model代表数据存储层,是对数据表的定义和数据的增删改查;
  • View代表视图层,是系统前端显示部分,负责显示什么和如何显示;
  • Controller代表控制层,负责根据从View层输入的指令来检索Model层的数据,并在改层编写代码产生结果并输出;
    MVC
    MVC设计模式的请求与响应过程描述如下:
  1. 用户通过浏览器向服务器发起request请求,Controller接受请求后,同时向Model和View发送指令。
  2. Mole根据指令与数据库交互并选择响应业务数据,然后将数据发送给Controller。
  3. View接收到Controller的指令,加载用户请求的页面,并将此页面给Controller。
  4. Controller接收到Model和View的数据后,将它们组织成响应格式发送给浏览器,浏览器通过解析后把页面展示出来。

MVC的3层之间紧密相连,但又相互独立,每一层的修改都不会影响其它层,每一层都提供了各自独立的接口供其它层调用,
MVC的设计模式降低了代码之间的耦合性(关联性),增加了模块的可重用性,这就是MVC的设计模式

MTV设计模式
django借鉴了经典的MVC模式,将交互的过程分为3个层次,也就是MTV设计模式:

MTV是Model-Template-View(模型-模板-视图)的缩写,主要用于django框架中。本质和MVC相同,Model依然表示数据和业务逻辑,View依然表示用户界面,但是Controller则变成Template。Template主要负责渲染数据到HTML模板,而View则负责数据的处理和逻辑判断。

  • model:数据存储层。处理所有数据相关的业务,和数据库交互,并提供数据的增删改查。
  • Template:模板层(表现层)。具体处理页面的显示。
  • View:业务逻辑层。处理具体的业务逻辑,它的作用是连通Model层和Template。
    MTV

按照MVC的设计模式对MTV进行分析,MTV设计模式中,用View层取代了Controller层位置,用Template层取代了原来的View层位置

MTV设计模式的请求与响应过程描述:

  1. 用户通过浏览器对服务器发起request请求,服务器接收请求后,通过View的业务逻辑层进行分析,同时像Model层和Template层发送指令;
  2. Model层与数据库进行交互,将数据返回View层;
  3. Template层接收到指令后,将用相应的模块,并返回给View层;
  4. View层接收到模板与数据后,首先对模板进行渲染(即将相应的数据赋值给模板),然后组织成响应格式返回给浏览器,浏览器进行解析后并最终呈现给用户。

通过以上两种设计模式的比较,可以得出MTV是MVC的一种细化,将原来MVC中的V层拿出来进行分离,视图的显示与如果显示交给Template层,而View层更专注于实现业务逻辑。其实django是有Controller层的,只不过由框架本身实现,所以不关心。

django安装与配置
django3.2支持python3.6、3.7、3.8和3.9 django4.1只支持python3.8、3.9和3.10

django3.2与4.1区别

  1. django自带的ASCI支持:

django3.2中,ASGI的支持已经得到了很大的改进,但是django4.1中,ASGI的支持得到了更多的增强和改进,包含更好的性能和更多的功能。

  1. type annotations支持:

在django3.2中type annotations得到了一些支持,但是django4.1中,得到了进一步的拓展和增强。

  1. admin后台管理:

django4.1对admin后台管理进行了一些改进,包含更好的UI设计、更好的性能和功能。
django4.1在官方文档中建议使用mysql5.7或mysql8.0进行数据库的存储,但也可以使用其他mysql版本。与python版本选择类似,选择mysql的版本主要考虑django4.1支持的版本以及个人项目实际需求。

cmd命令行安装django(可指定安装版本)

pip install django==4.1
# 使用可查看是否安装及安装版本
import django
django.get_version()
django项目
第一个项目(Bookstore) 方法一: 企业版直接建立就好 方法二: CMD命令创建
django-admin startproject Bookstore

创建项目
在这里插入图片描述
**** CMD创建static和templates文件夹不会自动创建,需手动添加(企业版自带templates好像,没钱没试过)
在这里插入图片描述
templates用于存放前端代码,static用于存放图片等。
django项目配置文件

  1. manage.py文件
    一级子目录中manage.py文件是管理django项目的重要命令行工具,主要用于启动项目、创建应用和完成数据库的迁移等。
  2. __ init __ . py 文件
    二级子目录中的__ init __ .py文件用于标识当前所在的目录是一个python包,如果此文件中,通过import导入其他方法或包会django自动识别。
  3. settings.py文件
    settings.py文件是django项目的重要配置文件。项目启动时,settings.py配置文件被自动调用,而它定义的一些全局为django运行提供参数,在此配置文件中也可以自定义一些变量,用于全局作用域的数据传递。
  4. urls.py文件
    url.py文件用于记录django项目的url映射关系,它属于项目的基础路由配置文件,路由系统就是在这个文件中完成相应配置的,项目中动态路径必须先经过文件配置,才能实现web站点上的资源访问功能。
  5. wsgi.py文件
    wsgi.py是WSGI服务器程序的入口文件,主要用于启动应用程序,遵守WSGI协议并负责网络通讯部分实现,只有在项目部署的时候在会用。
  6. asgi.py文件
    在django4.1中,创建asgi.py是为了支持ASGI协议的web服务器,以便更好支持异步I/O编程模型和更好的性能。
    ASGI协议代替了传统的WSGI(web server gateway interface)协议,在django3.0版本中开始支持ASGI,django4.1版本中进一步完善对ASGI的支持。
    asgi.py文件中默认包含ASGI应用程序实例,该应用程序实例管理了一系列的middlewares和routes等信息,用于处理用户端的请求,并返回响应数据。在使用ASGI协议时,可以通过asgi.py文件来配置ASGI应用程序,以便更好的支持异步I/O模型和更高性能。
启动django项目
启动项目命令
python manage.py runserver

运行后点击http://127.0.0.1:8000/跳转至项目启动页面
在这里插入图片描述
项目启动的默认端口8000
可以使用python manage.py runserver 7000修改端口号
settings.py配置文件
settings.py配置文件,django框架中重要的配置文件,定义一些全局变量来给django框架传递参数,还可以根据自己的实际需求来修改这个文件从而实现某些特定的需求。

  • BASE_DIR
    用于绑定当前项目BookStore所在的绝对路径,项目中的所有的文件都需要配置此路径:
BASE_DIR = Path(__file__).resolve().parent.parent
# __file__是python语法,显示当前文件位置。
  • SECRET_KEY
    SECRET_KEY是一个随机生成字符串,用于加密Cookie、密码等保密信息。django中最重要的安全设置之一。(注意:如果泄露了,可能会被黑客轻松破解获取私人信息)。

  • DEBUG
    用于配置django项目的启用模式,两种取值方式:
    DEBUG = True用于在开发环境中使用,属于调试模式,在项目的运行过中会暴露错误信息,方便调试。
    DEBUG=False用于线上环境,不启用调试模式。

  • ALLOWED_HOSTS
    指当目前项目中用来安装app列表,django把默认自带的应用放在这个列表中。(eg:admin后台应用等)

  • INSTALLED_APPS INSTALLED_APPS是一个非常重要的设置,可以根据自己的项目需求对其进行增加或删除,比如要单独开发一个后台管理系统,就可以把第一项admin注释。开发自己编写的应用都必须在这个变量中进行注册才能生效。(例如新建的app)

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
  • MIDDLEWARE
    用于注册中间件,django默认加载一些中间件
  • ROOT_URL_CONF
ROOT_URL_CONF='Bookstore.urls'
# 指定当前项目跟URL,是django路由系统入口。
  • TEMPLATES
    用于指定模板的配置信息,列表中每一元素都是一个字典。
  • WSGI_APPLICATION
    项目部署时,django的内置服务器将使用的WSGI应用程序对象的完整python路径。
  • DATABASES
    用于指定数据库配置信息,默认是django自带的sqllite3数据库。可以更改换为自己的数据库。
  • AUTH_PASSWORD_VALIDATORS
    这是一个支持插拔的密码验证器,且可以一次配置多个,django通过这写内置组件来避免用户设置密码等级不足问题。
  • LANGUAGE_GODE和TIME_ZONE
    分别代表语言配置项和当前服务器时区配置项,通常配置:
    LANGUAGE_CODE取值是英文:‘en-us’或者中文:‘zh-Hans’;
    TIME_ZONE取值是世界时区’UTC’或中国时区’Asia/Shanghai’.
  • USE_TI8N(国际化缩写)和USE_L10N(本地化缩写)
    项目开发完成后,可以选择向不同国家的用户提供服务。这两个变量值表达是否需要开启国际化和本地化功能(默认开启)
  • USE_TZ=TRUE
    指对时区处理方式,当设置为True时,存储到数据库的时间是世界时间’UTC’。
  • STATIC_URL=‘/static/’
    静态资源存放位置,包括CSS、JS、Images。
    创建数据库 —— CREATE DATABASE bookstoredb;
    settings.py文件中配置mysql数据库:
DATABASES={
	'default':{
		'ENGINE':'django.db.backends.mysql', # 数据库引擎
		'NAME':'数据库名', 
		'USER':'用户名',
		'PASSWORD':'密码',
		'HOST':'127.0.0.1',	# 主机ip
		'POST':3306, # 端口号
	}
}
django创建应用
  • django项目就是基于django框架开发的web应用,包含了一组配置和多个应用,称为APP。
  • 一个app就是一个python包,通常一个app可以包含模型、视图、模板和URL配置文件,可以被应用到多个django项目中,因为它们本质就是可被重用的python软件包。
    创建应用
    django设计目标是让开发者关注应用的功能逻辑的实现。
    可以使用:python manage.py startapp 应用名(新建应用之后记得添加INSTALLED_APPS列表中!)
    app
    其中:
  • admin.py:用于将model定义的数据表注册到管理后台,是django admin应用配置文件。
  • apps.py:用于应用程序本身的属性配置文件。
  • models.py:用于定义应用中所需要的数据表。
  • tests.py:文件用于编写当前应用程序的单元测试。
  • views.py:用来定义视图处理函数的文件。
  • 一级目录下的__init__.py文件标识index应用是一个python包
  • migrations:目录用于存储数据库迁移时生成的文件,改目录下的__init__.py文件标识migrations是一个python包。
django ORM
  • ORM即对象关系映射,一种基于关系型数据库的程序技术。ORM允许使用类和对象对数据库进行操作,这大大提高了队数据库的控制,避免了直接使用SQL语句对数据库进行操作。
  • Web开发中对数据库的操作必不可少的,但每种数据库的操作方式以及用法不尽相同。由于django中ORM的存在,为不同操作数据库提供了统一方法,ORM适配了多种常用的关系型数据库
    定义数据表
  1. 模型类
    其实模型类本质上属于一个python类,只不过在django中称之为模型类,由django.db.models.Model派出的子类通过上诉介绍,可以理解为:django中模型类相当于ORM模块。
  2. 定义数据表
# 导入models模块
from django.db import models
# 使用class关键字对UserInfo表进行类定义,并继承models模块中的Model类
class UserInfo(models.Model):
	# 设置字段定义字段长度
	name = models.CharFiled(max_length=100)
	password = models.CharFiled(max_length=100)

配置models.py文件(设置基本字段):

class Book(models.Model):
    title = models.CharField(max_length=30, unique=True, verbose_name='书名')
    public = models.CharField(max_length=50, verbose_name='出版社')
    price = models.CharField(max_digits=7, decimal_places=2, verbose_name='定价')
    retail_price = models.DecimalField(max_digits=7, decimal_places=2, verbose_name='零售价', default='30')


class Author(models.Model):
    name = models.CharField(max_length=30, verbose_name="姓名")
    email = models.EmailField(verbose_name="邮箱")


class UserInfo(models.Model):
    username = models.CharField(max_length=24, verbose_name="用户注册")
    password = models.CharField(max_length=24, verbose_name="密码")

通用字段选项
Model中添加的字段都是Field类型的实例,不同的Field类型可能会支持不同字段选项,但是也有很多字段选项是通用的,即可以用在任何一种Field类型中,下面是一些常用且较为重要的字段选项。

  • blank
    默认值false,设置为true时,字段可以为空。设置为false时,字段必须填写的。如果是字符型字段CharField和TextField,是用于空字符串存储空值的。
  • unique
    默认值是false,它是一个数据库级别的选项,规定该字段在表中必须是唯一的。
  • null
    默认为false,如果此选项为false建议加入default选项来设置默认值。如果设置为true,表示该列值允许为空。日期型、时间型以及数字型字段不接收空字符串。所以当设置integerfild,datatimefield型字段可以为空时,需将blank与null均设为True才可以。
  • db_index
    默认值是false,如果设置为true,django则会为该字段创建数据库索引,如果该字段经常作为查询条件,那么需要设置db_index选项,从而加快数据的检索速度。
  • db_column
    这个选项用于设置数据库表字段的名称,如果没有指定,django默认使用model中字段名字。
  • default
    用于给字段设置默认值,该选项可以设置一个值或可以调用对象,但不能是可变对象,不同字段类型默认值也不同,eg:booleanfiled布尔类型default值为true或false。主要使用场景是当一个字段的值被用户省略时,后天服务器自动为该字段设置默认值。
  • primary_key
    默认值为false,如果设置为true,表示该字段为主键,在django中默认id为主键,也就是即使数据表中没有创建id字段,django也会自动创建id字段并设置为主键。如果设置了其他字段为主键时,那么django将取消为id字段设置主键。
  • choices
    给字段设置可以选择的值,一个可迭代对象,即列表或元组,其中每一个元素都是一个二元组(a,b)形式,a是用来选择的对象,b是对a的描述信息。eg:
# 创建表
class UserInfo(models.Model):
	# 定义chocies参数对应关系,以元组(列表)形式进行表述:
	choices = (
		(male,'男性'),
		(female,'女性'),
	)
	gender = models.CharField(max_length=2,choices=choices,default='male')
  • verbose_name
    设置此字段为admin后台管理系统界面上的显示名称,如果没有设置,django将会直接展示子弹并将字段中的下划线转变为空格。
    外键使用
    有一个数据表,就应该对应一个模型 在models.py中定义模型
from django.db import models
class Grades(models.Model):
	"""班级表"""
	gname = models.CharFiled(max_length=20)	# 班级名
	gdate = models.DateTimeField()	# date
	gtotal = models.IntegerField()	# total
class Students(models.Model):
	"""学生表"""
	sname = models.CharField(max_length=20)	# name
	sgender = models.BooleanField(default=True)	# gender
	sage = models.IntegerField()	# age
	sgrade = models.ForeignKey(Grades,models.DO_NOTHING)
on_delete = None , # 删除关联表中的数据时,当前表与其关联的field的行为
on_delete = models.CASCADE,	# 删除关联数据,与之关联也删除
on_delete = models.PROTECT,	# 删除关联数据,引发错误ProtectedError
models.ForeignKey('关联表',on_delete=models.SET_NULL,blank=True,null=True)
on_delete=models.SET_NULL, # 删除关联数据,与之关联的值设置为null(前提FK字段需要设置可空,一对一同理)
models.ForeignKey('关联表',on_delete=models.SET_DEFAULT,default='默认值')
on_delete=models.SET_DEFAULT,	# 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理) 

应用数据库迁移

python manage.py makemigrations
python manage.py migrate

运行后会生成00001_initial.py文件,包含了创建数据表时用到的所有信息,这是一个临时的过度文件。
makemigrationsmigrate是django中的两个命令,用于数据库迁移和同步模型。

makemigrations命令基于django中模型定义,生成一组迁移文件,这些文件描述如何在数据库中创建或修改表结构,在执行makemigrations命令时,django会比较当前模型定义与最近一次迁移所定义的模型之间的差异,并生成一系列SQL命令执行更改。

migrate命令用于应用迁移,它将迁移文件中定义的更改应用到数据库中。执行命令时,django会检查其中的每个迁移,执行其中定义的sql命令,并将这些更改反映到数据库模式中。如果执行成功,django应用的数据模型和数据量之间保持同步了。

makemigrations命令会生成迁移文件,描述如何在数据库中创建或修改表结构,而migrate命令会将这些迁移文件应用到数据库中,使数据模型保持和数据库之间的同步。这两个命令通常会在django开发过程中被频繁使用,需要对数据库进行修改,增加和删除操作。

django admin数据表
后台管理

django admin后台管理是django自带的一个功能强大的应用程序,可以帮助开发人员快速构建一个完全可指定的管理界面。通过在admin后台管理,管理员可方便的修改和管理网站中的数据库内容,无需写代码。提供对django模型的CRUD操作(增删改查)功能,并支持高级功能,eg:搜索、筛选、排序、分许、导出、导入 、导出数据等,管理员只需要简单的图形界面就可以完成所有操作。
开发人员可以通过django中创建数据库模型类,自动构建一个功能强大的管理界面,需要自己设计或编写管理界面所需HTML、CSS、和javascript等代码。管理员可以登录后台管理界面,在列表视图中查看并操作所有可管理的模型,也可以使用自定义表单展示数据、筛选、搜索、排序、分页等功能。
django admin优点:

  • 快速创建:通过在数据库模型上增加admin.site.register注册,就可以获得一个基本的管理页面。
  • 前后端分离:无需自定义管理页面的前端代码,只需专注于编写后台数据库模型类。
  • 自定义灵活:可以通过自定义的admin类,对admin展示页面进行拓展、定制和优化。
  • 安全性:可以对每个用户进行授权和权限管理,比如只需要管理员进行某些操作。

总体而言,django admin后台管理是django框架的重要组成部分之一,提供强大、灵活、安全的管理界面,使得管理员可轻松的管理和操作数据库内容。

创建超级用户
创建超级用户 python manage.py createsuperuser
依次输入用户名、邮箱、密码
进入网址http://127.0.0.1:8000/admin/输入账号登录

python manage.py createsuperuser -- username =用户名  --email=邮箱
# 添加内容带表直接设定账本密码,如不添加内容,django会提示用户输入用户名和邮箱。当执行命令后,需要重复输入两次密码(密码不能过于简单)
# 输入密码时候不会显示密码
# 超级用户拥有所有权限(增、删、改、查等)

输入后提示Superuser created successfully.代表创建成功。运行项目后,进入http://127.0.0.1:8000/admin/,输入设置的用户名及密码,可进入到管理员界面在这里插入图片描述
数据表注册

admin.py文件中声明
使用startapp命令创建index应用的时候会自动创建admin.py文件,想要把自定义的model注册到管理后台,就需要在admin.py文件中声明。

from django.contrib import admin  # Django自动在admin.py文件中导入
from .models import Book, Author, UserInfo  # 这个需要我们自己导入相应的模型类(数据表)
admin.site.register(Book)
admin.site.register(Author)
admin.site.register(UserInfo)
# admin.site.rigister([Book,UserInfo,Author])

通过django.contrib标准库引入admin应用,然后把index应用下自定义的表单引入,最后调用admin.site.register()方法实现模型类注册。这样就将model注册到后台管理系统中了。
如需单一的模型类注册,可以使用admin.site.register(Book)
管理员

页面简单且并无很多附加功能,但使用简单的增删改查已经足够。
建立后进入查看,每张数据表名字都加上了S,这是django自动设定的。(可以自行更改)。

admin操作日志

admin应用在数据库迁移过程中只创建了django_admin_log一张表,用于记录通过管理后台对Model的增删改操作创建的所有数据表
django_admin_log中的字段

含义:

  • id:自增主键。
  • action_time:datetime类型,保存操作发生的日期和时间。
  • object_id:longtext类型,保存修改对象的主键。
  • object_repr:varchar类型,保存修改后的对象执行类型repr函数的值,repr是python内置函数,将对象转化为字符串。
  • action_flag:无符号smallint类型,用于记录操作类型ADDITION(值为1,表示添加)、CHANGE(值为2,表示更新)、DELETION(值为3,表示删除)。
  • change_message:longtext类型,用于保存修改对象的详细描述。
  • content_type_id:int类型,外键关联ContentType对象。
  • user_id:int类型,外键关键User对象(默认值),记录执行操作的用户。
数据表显示
字段显示

在数据库字段中,有一些数据不需要显示给后台的,可以将字段进行指定的显示,使得页面更加整洁。

# 设置表中需要显示的数据
from django.contrib import admin # Django自动在admin.py文件中导入
from index.models import Book,Author,UserInfo	# 导入自己响应的模型类(数据表)
class AuthorAdmin(admin.ModelAdmin):
	fields = ('author_id',)	# 需要显示的字段
admin.site.register(Author,AuthorAdmin)
admin.site.register([Book,UserInfo])

表单显示分块
可以将输入栏分块,每个栏自定义格式

fieldsets = (
	['Main',{
		'fields':('author_id',),
	}],
	['Advance',{
		'classes':('collapse',),
		'fields':('email',),
	}]
)

Main和Advance两部分。classes说明所有的部分是CSS格式。

这里让Advance部分隐藏:‘class’😦‘collapse’,)显示将该字段设置折叠状态,以便用户需要时选择展开。

内联显示
内联基础是需要两个表有外部键,所以有外部参考关系

在默认的页面显示中,将两者分离开来,无法体现出两者的从属关系。我们可以使用内联显示,让一个页面附件在另外一个页面的编辑页面上显示。

from django.contrib import admin
from import_export.admin import ImportExportModelAdmin
from book.models import Author,Book
class TagInLine(admin.TabularInline):
	model = Book
	extra = 1 # extra参数指定了默认行的数量
@admin.register(Author)	# 新的注册写法
class AuthorAdmin(ImportExportModelAdmin,admin.ModelAdmin):
	fields = ('name','email','gender')	# 需要显示的字段
	list_display=('name','email')
	search_fields = ('name','email')
	list_filter = ('age',)
	ordering = ['email',]
	inlines = [TagInline]
	list_per_page = 50	# 添加每页记录数
    fieldsets = (['Main', {
        'fields': ('name', 'email'), }],
                 ['Advance', {
                     # 'classes': ('collapse',),
                     'fields': ('age', 'gender'), }]
                 )
admin.site.register([Book])	# 注册表

列表显示
也可以自定义该页面显示。eg:在列表中显示更多的栏目,用于增加和显示更多的列。

class AuthorAdmin(admin.ModelsAdmin):
	list_display('author_id','email')

搜索栏目创建

作用增加搜索组件,并且搜索指定的字段数据。

class AuthorAdmin(admin.ModelAdmin):
	search_dosplay = ('name',)

筛选
对数据列进行筛选获取筛选后的数据。

class AuthorAdmin(admin.ModelAdmin):
	list_filter = ('author_id',)

排序
对列数据进行排序

class AuthorAdmin(admin.ModelAdmin):
	ordering = ['email',]	# 添加一个排序选项

分页
记录过多可以使用分页进行分页的显示

class AuthorAdmin(admin.ModelAdmin):
	list_per_page = 50	# 添加每页记录数

导入导出
在django Admin后台管理中,还可以导入导出数据。

  1. 安装django-import-export模块。
pip install django-import-export
  1. 确认安装并在INSTALLED_APPS中注册了import_export应用程序
from import_export.admin import ImportExportModelAdmin	# 一定要导入  导入导出模块
class BookAdmin(ImportExportModelAdmin,admin.ModelAdmin):
django模板

django模板系统的将python代码与HTML代码解耦,动态地生成HTML页面。django项目可以配置一个或多个模板引擎,但是通常使用django模板系统时,应首先考虑其内置的后端DTL(DTL是一种用于创建模板变量和标签的语言,允许在模板中引用python变量和编码,并在web应用程序中生成动态内容)模板语言。

what is 模板
在django中,模板是可以根据字典数据动态变化的,并且能够根据视图中传递的字典数据动态生成相应的HTML网页。django中使用Template来表示模板,Template对象定义在template文件中(社区版通过cmd创建的文件需要自己手动建立文件夹哦!!!)

配置模板
运用模板需在settings.py配置文件中进行配置

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR / 'templates')],	# 指定模板文件的存放路径
        'APP_DIRS': True,	# 搜索APP里所有template目录
        'OPTIONS': {
            'context_processors': [	# context_processors用于配置模板上下文处理器
        			'django.template.context_processors.debug',
					'django.template.context_processors.request',
					'django.contrib.auth.context_processors.auth',  
					'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
  • BACKEND:django默认设置,指定要用的模板引擎的python路径;
  • DIRS:一个目录列表,指定模板文件的存放路径,可以是一个也可以是多个。模板引擎将按照定义中顺序查找模板文件;
  • APP_DORS:布尔值,默认true。表示会安装应用中的templates目录中搜索所有模板文件;
  • OPTIONS:指定额外选项,不同的模板引擎有这不同的可选参数例如context_processors用于配置模板上下文处理器,在使RequestContext时将看到其作用;
    使用模板

在django应用程序中的templates目录中创建一个新的模板文件,eg:hello.html,然后再文件中编写一下html代码:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Hello</title>
</head>
<body>
	<h1>hello,{{ name }}!</h1>
</body>
</html>

其中{{ name }}是由两个括号包裹的变量,当django渲染模板时,会查找模板上下文中的name变量,并将其值替换为模板中的变量。最终,模板引擎会将渲染后的HTML网页发送给浏览器。

通过render方法直接加载并响应模板:

from django.shortcuts import render
return render(request,'文件名',字典数据)

一个简单的事例:

# 在index/views.py文件中添加
from django.shortcuts import render
def hello(request):
	context = {
		'name':'啥也不是',	
	}
	return render(request,'hello.html',context)

需要在django中定义视图函数处理来自浏览器的HTTP请求,当然这只是其中一部分,还需配置URL映射、编写模板等等。

在BookStore/urls.py文件的urlpatterns列表为视图函数配置路由映射关系。

from django.contrib import admin
from django.urls import path
from index import views	# 导入的视图
urlpatterns = {
	path('admin/',admin.site.urls),
	path('hello/',views.hello)	# 当访问路径下的hello路径时,返回视图中hello函数
}

上段代码定义了django URL常规写法,包括两个URL映射规则:

  1. 第一个URL映射规则将浏览器输入的URL路径/admin/映射到django管理后台。
  2. 第二个URL映射规则将浏览器中输入的URL路径/hello/映射到views.hello视图函数。
  3. 其中,第二个URL映射规则,通过path()函数指定一个URL路径/hello/,并将它映射到名为views.hello的视图函数。
  4. 代表着当django应用程序接收到浏览器中的/hello/请求时,django将自动调用views.hello(request)来响应改请求,其中request参数将包含来自浏览器的HTTP请求对象。
  5. 在views.py文件中,我们必须定义一个名为hello()的函数,以匹配URL映射规则。您可以在改函数中编写所需的python代码,以生成http响应并发送回浏览器。
    此时上面这种方式,完成了一个简单的实例。

除去以上方法,还可以通过loader获取模板,通过HttpResponse进行响应

from django.http import HttpResponse
from django.template import loader
content = {
	'name':'苯环',
}
# 1.通过loader加载模板
t = loader.get_template('hello.html')
# 2.将t转化为html字符串
html = t.render(context)
# 3.用响应对象将转换的字符串内容返回浏览器
return HttpResponse(html)

django视图函数实现流程:

  1. templates文件中建立html文件,以做模板;
  2. 为模板文件配置对应的视图,为模板进行传参;
  3. 然后配置了视图函数的路由映射关系,访问视图;

render方法详解

render方法的作用是结合一个给定的模板和一个给定的字典,并返回一个渲染后的HttpResponse对象。简单的说就是把字段格式内容加载进templates目录中定义的html文件,最终通过浏览器渲染呈现。

完整的render()方法参数格式如下:

render(request,template_name,context=None,content_type=None,status=None,using=None)

其中每个参数的含义:

  • request:一个固定参数,用于生成响应的请求对象。
  • template_name:templates中定义的文件,要注意路径名。eg:“templates\appname\inedx.html”,参数要写"appname\index.html"
  • context:要传入文件中用于渲染呈现的数据,默认是字典格式;
  • content_type:生成文档要使用的媒体格式类型。默认为DEFAULT_CONTENT_TYPE设置的值;
  • status:http响应代码,默认是200;
  • using:用于加载模板使用的模板引擎名称;
模板变量使用
模板变量是指在模板中使用的变量,通过丛视图函数中传递过来的。 django模板语言的语法主要分为以下四个部分:
  • 变量
  • 标签
  • 过滤器
  • 注释

模板变量

  • 前面内容中提到了模板变量,并且使用了它{{ name }}。
  • django模板引擎通过上下文处理器来完成字典提供的值(value)
  • 与模板变量之间的替换,也就是用字典的value来替换模板文件.html中的变量{{name}},就好比字典中key到value映射,而我们无需关心内部细节是如果实现的,这些由的激昂平框架自己完成。
  • 变量的命名规范

django对于模板变量的命名规范没有太多要求,可以使用字母、数字和下划线组成来命名,且必须以字母或下划线开通,但是变量名称中不能有空格或标点符号。

  • 模板变量的语法
    有四种不同的使用场景:
  • 索引index查询,eg:{{变量名.index}},其中index为int类型即索引下标
  • 字典查询方式,{{变量名.key}}其中key代表字典的键,eg:a[‘b’]
  • 属性或方法查询:eg:{{对象.方法}},把圆点前内容理解成一个对象,把圆点后内容理解为对象中的属性或方法
  • 函数调用,eg:{{函数名}}

代码实例:
在views.py中添加代码:

def test_hello():
	return '我是函数的返回数据'
class WebSite:
	def web_name(self):
		return 'hello world!'
def test_html(request):
	a = {'name':'xxx',
		'list_obj':["python","C","C++","Java"],
		'dict_obj':{'name':'百度','address':'https://www.baidu.com/'},
		'func':test_hello,
		'class_obj':WebSite()	# 创建空字典,模板必须以字典的形式进行传参
	}
	return render(request,'test_html.html',a)

然后再templates目录下创建名为test_html的html文件,然后添加代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>名字是{{ name }}</p>
<p>列表数据是{{ list_obj }}</p>
<p>课程是{{ list_obj.0 }}</p>
<p>变量dict_obj是{{ dict_obj }}</p>
<p>dict_obj['address']是{{dict_obj.address}}</p>
<p>函数fuction:{{ func }}</p>
<p>类实例化对象:{{class_obj.web_name}}</p>
</body>
</html>

然后再url.py文件中添加路由配置,如下所示:

from django.contrib import admin
from django.urls import path
from Bookstore import views
urlpatterns={
	path('test_html/',views.test_html)
}

访问指定的路径就可以访问到页面了。

模板传参语法格式:

在视图函数中必须将变量封装到字典中才允许传递到模板上,语法格式如下:

# 方式1
def xxx_view(request)
	dic = {
		"变量1":"值1",
		"变量2":"值2",
	}
	return render(request,'xxx.html',dic)
# 方式2
def xxx_view(request)
		变量1 =1
		变量2 =2
	return render(request,'xxx.html',locals())

注意:

locals()返回当前函数作用域内全部局部变量形成的字典。
               即将变量与值对应形成字典,并将这个字典作为locals()的返回值来使用。

模板标签

django内置许多标签的解释是在渲染的过程中提供相应的逻辑,eg:python语言中if…else语句、with语句、for循环等,这些在django的模板系统中都有对应的标签,不过稍等复杂些。

使用方式:{% tag %}
if标签

if在python语言中是判断条件是否成立的,在模板标签中它们作用是类似的,如果条件成立则显示块中的内容。

模板标签规定if需要与endif成对出现,使用方式如下:

{% if 条件表达式1 %}
	…………
{% elif 条件表达式2 %}
	…………
{% elif 条件表达式3 %}
	…………
{% else %}
	…………

上列事例中就是使用了开始标签和结束标签,它们分别写在开始位置和结束位置。

注意:模板标签内部的两边空格不能省略。
例子:

# 在views.py中添加如下代码
def test_if(request):
	dic={'x':2**4}
	return render(request,'test_if.html',dic)

在templates目录中创建test_if.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% if x > 0 %}
        <h2>{{ x }}是大于0的</h2>
    {% elif x == 0 %}
        <h3>{{ x }}是等于0的</h3>
    {% elif x < 0 %}
        <h4>{{ x }}是小于0的</h4>
    {% endif %}
</body>
</html>

最后在urls.py文件中配置路由:path('test_if/',views.test_if)

上面例子中可以看出,if标签中可以使用算术操作符,eg:>、<、==、<=等符号,同时也可以使用运算符and、or来连接多个条件,以及使用not对当前条件取反。

注意:elif和else两个标签是可选的,elif标签可以不止一个,但是else标签只有一个,同时也可以都不出现在if标签中,只使用if与endif。
当判断条件太多时,为避免过多连接操作符出现,同样可以考虑使用if标签。

{% if条件表达式 %}
	{% if 条件表达式2 %}
	   …………
	 {% elif 条件表达式3 %}
	   …………
	  {% else %}
	   	…………
	   {% endif %}
{% endif % }

简单的演示使用if标签。在views.py中添加代码:

from django.template import Template,Context	# 调用template、以及上下文处理器方式
def Hello_MyWeb(request):
	# 调用template()方法生成模板
	t = template("""
				{% if web.name == 'xx' %}
					{% if printable %}
						<h1>Hello xx</h1>
					{% else %}
						<h2>欢迎下次访问,xx</h2>
					{% endif %}
				{% endif %}
			""")
	c = Context({'web':{'name':'xx'},'printable':True})	# context必须是字典类型对象,用于给模板传递数据
	html = t.render(c)
	return HttpResponse(html)

在urls.py文件中为hello_MyWeb()函数配置路由映射关系:path('Hello_MyWeb/',views.Hello_MyWeb)

以上讲解了Django模板标签中的if标签的使用方法。django是基于python的web框架,有自己的特点,但是离不开python语音,所以学会结合python语言去学习会更快的掌握相关知识。

for标签

for标签用于对可迭代对象进行遍历,包括列表、元组等,它与python中的for语法是类似的。for标签使用时也需要和endfor标签配合使用。当然也有不同之处,多了一个可选empty标签,比如用它来 显示当列表不存在或者列表中元素为空的时候要显示的内容。

格式:

{% for变量 in 可迭代对象 %}
	……循环语句
{% empty %}
	……可迭代对象无数据时填充语句
{% endfor %}

实例:

def test_for(request):
	# 调用template()方法生成模板
	t1 = Template("""
		{% for item in list %}
			<li>{{ item }}</li>
		{% empty %}
			<h1>如果找不到你想要,可以百度(网址:https://www.baidu.com)</h1>
		{% endfor %}
	""")
	# 调用context()方法
	c1 = Context({'list':['Python','Java','C','Javascript','C++']})
	html = t1.render(c1)
	return HttpResponse(html)

配置映射关系:path('test_for/',views.test_for)
提示:与python中的for循环不同的是,for标签只能一次性地遍历完列表中的元素,不能中断(break),也不能跳过(continue)
forloop变量

在for标签还提供了内置变量forloop,我们可以访问这个变量的属性从而获取for循环迭代过程中的一些信息,eg:forloop.first,它的返回值是一个布尔值,当for循环迭代第一个元素的时候返回True,若有其余元素则返回False。

变量描述
forloop.counter用来计数,查看当前迭代第几个元素(从1开始索引)
forloop.revcounter表示当前循环中剩余的未被迭代的元素数量(从1开始索引)
forloop.first如果当前迭代的是第一个元素,则为true
forloop.last如果当前迭代的最后一个元素,则为true
forloop.parentloop在嵌套循环中,用来引用外层循环的forloop

例子:

def test_forloop(request):
	a = Template("""
		{% for item in lists %}
		<div>
			<p><b>{{ forloop.counter }}:{{ item }}</b></p>
		</div>
	""")
	b = Context({'lists':['c语言','django官网','python官网']})
	html = a.render(b)
	return HttpResponse(html)	# 数字与元素以1:‘c语言’形式出现

映射:path('test_forloop/',views.test_forloop).
实例:
forloop.revcounter表示当前循环中剩余的未被迭代的元素数量(1开始索引)

{% for num in numbers %}
	{{ num }} ({{ forloop.revcounter }} left)
{% endfor %}

假设numbers列表包含[2,4,6,8,10],则渲染结果为:

25 left)
44 left)
63 left)
82 left)
101 left)

forloop.first和forloop.last实例
forloop.first如果当前迭代的是第一个元素,则为true
forloop.last如果当前迭代的是最后一个元素

{% for i in list1 %}
        
        {% if forloop.first %}
            <p>通过forloop.first 获取到第一个参数{{ i }}</p>
        {% elif forloop.last %}
            <p>通过forloop.last 获取到最后一个参数{{ i }}</p>
        {% else %}
            <p>{{ i }} 的计数是 {{ forloop.counter }} ,后面未被迭代的数据为 {{ forloop.revcounter }} </p>
        {% endif %}
        
    {% empty %}
        <p>列表中没有数据</p>
    {% endfor %}

forloop.parentloop实例
forloop.parentloop在嵌套循环中,用来引用外层循环的forloop

{% for category in categories %}
  <h2>{{ category.name }}</h2>
  {% if category.products %}
    <ul>
      {% for product in category.products %}
        <li>{{ product.name }}</li>
      {% endfor %}
    </ul>
  {% endif %}
{% endfor %}

假设categories列表包含两个对象,每个对象包含一个名称属性和一个产品列表属性。渲染结果将输出每个类别的产品列表,最后还要输出类别的总数

在内部循环中,我们可以使用forloop.parentloop引用外部循环上下文,这里它允许我们检查是否在迭代列表内最后一个元素,以便在所有类别都遍历后输出总数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值