只要你是做后端开发的,那么就离不开各种数据库,Django框架对各种数据库都非常友好,比如常见的PostgreSQL、MySQL、SQLite、Oracle,django都对他们提供了统一调用api,我们这里主要使用mysql数据库作为演示
ORM机制,又称为对象关系映射,简单来说就是通过定义python文件中的class类,然后通过ORM将python代码转换成sql语句,再通过pymysql库链接到mysql数据库,执行sql语句
1、ORM 会将 Python 代码转成为 SQL 语句。
2、SQL 语句通过 pymysql 传送到数据库服务端。
3、在数据库中执行 SQL 语句并将结果返回。
#部署容器
docker run --name mysql8 \
-p 30013:3306 \
-d \
-v /home/data/mysql/conf/my.cnf:/etc/mysql/my.cnf \
-v /home/data/mysql/data:/var/lib/mysql \
-v /home/data/mysql/log:/logs \
-e MYSQL_ROOT_PASSWORD=123456 \
--restart=always mysql:8.0 \
--lower_case_table_names=1
#创建数据库
create database paas default charset=utf8;
#授权
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
ORM机制无法创建数据库级别操作,只能创建表
pip3 install pymysql
pip3 install cryptography
vi Django_demo\Django_demo\settings.py
#找到DATABASES 修改配置
DATABASES = {
'default':
{
'ENGINE': 'django.db.backends.mysql', # 数据库引擎
'NAME': 'paas', # 数据库名称
'HOST': '101.43.156.78', # 数据库地址
'PORT': 3306, # 端口
'USER': 'root', # 数据库用户名
'PASSWORD': '123456', # 数据库密码
}
}
在settings.py的同级目录下找到__init__.py 文件添加
vi Django_demo\Django_demo\__init__.py
# 在与 settings.py 同级目录下的 __init__.py 中引入模块和进行配置
import pymysql
pymysql.install_as_MySQLdb()
django-admin startapp paas
vi Django_demo/paas/models.py
from django.db import models
#相当于是定义了表中存储数据的字段
class PaasInfo(models.Model):
# 集群名称
ClusterName = models.CharField(max_length=200)
# node主机数量
NodeSum = models.CharField(max_length=200)
# prometheus地址
PrometheusAddress = models.CharField(max_length=200)
配置说明
class PaasInfo #定义数据表的名称 class 等同于数据库中的表
ClusterName = models.CharField(max_length=200)
ClusterName #定义数据表中字段的名称
models.CharField #字段类型为字符串 (varchar)
max_length=200 #字段数据长度最大为200字节
vi Django_demo/paas/apps.py
#这里的name相当于是当前应用的唯一标识
class CommonConfig(AppConfig):
name = 'paas'
#说明
CommonConfig 类是一个继承自 AppConfig 的应用程序配置类。
这个类的作用是为定义的应用程序提供配置信息。在 CommonConfig 类中,name 属性被设置为 'paas',表示该应用程序的名称是 "paas"。
通过在应用程序中定义一个配置类,您可以为应用程序指定自定义的配置参数。这些配置参数可以在 Django 的设置文件中进行进一步的配置,例如指定模型文件、URL 路由和静态文件位置等。
对于一个简单的 Django 应用程序来说,name 属性的设置是必需的,它用于唯一标识应用程序并在 Django 项目中进行引用。其他的配置参数包括 verbose_name 属性,用于指定应用程序的显示名称。
vi Django_demo/Django_demo/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#添加如下配置,也可以直接写paas
'paas.apps.CommonConfig',
]
这里有个小区别说明一下,上面的'paas.apps.CommonConfig', 也可以写错'paas',
通过直接添加
paas
, Django 将使用默认的应用程序配置类来初始化该应用程序。通过添加'paas.apps.CommonConfig'
,可以指定自定义的应用程序配置类,并且可以在其中定义更多的配置参数和行为。
#命令大意为 查看paas应用下的models.py 定义了什么
#将定义的语句转换成操作数据库的脚本文件
python manage.py makemigrations paas
返回
Migrations for 'paas':
paas\migrations\0001_initial.py
- Create model PaasInfo
上面获取到的信息中Django_demo/paas/migrations/0001_initial.py 是我们基于定义的model获取到的用于创建数据库和表的一个python语句
python manage.py migrate
返回
Operations to perform:
Apply all migrations: admin, auth, contenttypes, paas, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying paas.0001_initial... OK
Applying sessions.0001_initial... OK
#登录paas数据库
use paas
#查看paas库下的表
show tables;
#查看表结构
desc paas_paasinfo;
如果以后我们修改了Models.py 里面的库表的定义,都需要再次运行 python manage.py makemigrations common 和 python manage.py migrate 命令,使数据库同步该修改结果
Django提供了一个管理员操作界面可以方便的 添加、修改、删除你定义的 model 表数据
python manage.py createsuperuser
#填写
用户 root
邮箱 [email protected]
密码 12345678
再次输入密码 12345678
vi Django_demo/paas/admin.py
from django.contrib import admin
# Register your models here.
from .models import PaasInfo
admin.site.register(PaasInfo)
启动服务
python manage.py runserver
访问页面
http://127.0.0.1:8000/admin/
pip3 install django-simpleui
vi Django_demo/Django_demo/settings.py
INSTALLED_APPS = [
'simpleui', #添加到第一行
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'paas',
]
select * from paas_paasinfo;
我们在上面实现了链接数据库并插入数据,如果我们想要将数据从数据库读取出来,并且打印到页面上,应该怎么操作呢,下面我们尝试实现访问/
sales/SelectHost 路径时返回数据库中
PaasInfo 表下的所有数据
vi Django_demo/Django_demo/urls.py
from django.contrib import admin
from django.urls import path
#添加
from django.urls import include
urlpatterns = [
path('admin/', admin.site.urls),
#在主路由上添加,当请求sales开头时都会把请求交给paas应用下的urls
path('sales/', include('paas.urls')),
]
添加后就允许子应用添加自己的路由配置了
vi Django_demo/paas/views.py
from django.http import HttpResponse
from .models import PaasInfo
def listcustomers(request):
#拿到我们之前定义的表的模型函数,请求后返回一个包含所有数据的QuerySet对象
#每行数据都是一个dict, key的名称是字段名 Value是值
qs = PaasInfo.objects.values()
# 定义返回字符串
retStr = ''
for customer in qs:
for name,value in customer.items():
retStr += f'{name} : {value} | '
#
表示换行,在返回值中带上换行,那么页面上显示也会生效
retStr += '
'
return HttpResponse(retStr)
vi Django_demo/paas/urls.py
from django.urls import path
from .views import listcustomers
urlpatterns = [
#paas应用上的路由只需要定义自己路由的部分即可
path('SelectHost/',listcustomers ),
]
http://127.0.0.1:8000/sales/SelectHost/
有的时候,我们需要根据过滤条件查询部分客户信息
比如,当用户在浏览器输入 http://127.0.0.1:8000/sales/SelectHost/?NodeSum=123123
可以查询到node主机数量为123123台的信息,实现他的方法是添加filter方法进行过滤
vi Django_demo/paas/views.py
def listcustomers(request):
#获取表全量数据
qs = PaasInfo.objects.values()
#检查url中是否有参数NodeSum
#如果没有值,则返回给ph值为后面的None
ph = request.GET.get('NodeSum',None)
#判断如果有的话, 就将值赋予给字段进行筛选后赋值覆盖全量数据
if ph:
qs = qs.filter(NodeSum=ph)
# 循环遍历全量数据并打印到页面
retStr = ''
for customer in qs:
for name,value in customer.items():
retStr += f'{name} : {value} | '
#
表示换行
retStr += '
'
return HttpResponse(retStr)
测试
http://127.0.0.1:8000/sales/SelectHost/?NodeSum=123123
上面我们返回给页面的数据如下,非常杂乱并不方便查看,因为我们只是将数据返回给页面,而返回的页面并没有css、js等样式或功能,我们下面给返回的数据添加一些显示格式
html代码本身也是字符串,我们可以把整个html定义到我们程序中的字符串进行接收
vi Django_demo/paas/views.py
from django.http import HttpResponse
from .models import PaasInfo
#添加html模板变量
html_template ='''
id
姓名
电话号码
地址
%s
'''
def listcustomers(request):
qs = PaasInfo.objects.values()
ph = request.GET.get('NodeSum',None)
if ph:
qs = qs.filter(NodeSum=ph)
# 生成html模板中要插入的html片段内容
tableContent = ''
for customer in qs:
tableContent += '' #没循环一次取到的数据都换到零一和
for name,value in customer.items(): #取每个字段的数据,并作为当前行的值
tableContent += f'{value} '
tableContent += ' ' #最后添加 表示当前行结束
return HttpResponse(html_template%tableContent) #模板变量名称 + % + 返回数据的模板
测试
我们用一个变量 html_template 存储html模板, 然后 代码中生成html 里面需要插入的表格记录的内容,这个内容是html片段,也就是 html 表格的每行 。
上面我们直接定义在变量中的html并不方便管理 很多后端框架都提供了一种 模板技术, 可以在html 中嵌入编程语言代码片段, 用模板引擎(就是一个专门处理HTML模板的库)来动态的生成HTML代码,Python 中有很多这样的模板引擎 比如 jinja2 、Mako, Django也内置了一个这样的模板引擎,我们这里使用django 去渲染html
from django.http import HttpResponse
from .models import PaasInfo
#添加html模板变量
html_template ='''
id
姓名
电话号码
地址
{% for customer in customers %}
{% for name, value in customer.items %}
{{ value }}
{% endfor %}
{% endfor %}
'''
from django.template import engines
django_engine = engines['django']
template = django_engine.from_string(html_template)
def listcustomers(request):
qs = PaasInfo.objects.values()
ph = request.GET.get('NodeSum',None)
if ph:
qs = qs.filter(NodeSum=ph)
# 传入渲染模板需要的参数
rendered = template.render({'customers':qs})
return HttpResponse(rendered)
使用上面的方法发现可以实现同样的显示效果,不过我们不需要在后端的函数中去定义各种tr这种属于前端页面显示的元素了,而是通过模板将需要返回的数据以变量 customers 交给页面,然后在使用下面for循环去变量从django拿到的数据进行展示
{% for customer in customers %}
{% for name, value in customer.items %}
{{ value }}
{% endfor %}
{% endfor %}
有了模板引擎,对我们后端开发来说,简化了程序员后端生成HTML的任务
但是,通常来说后端开发的核心任务不是开发前端界面,并且大部分后端开发人员对前端界面开发还是不熟悉的,前端页面要是要前端开发去做
如果动态的界面内容都是由后端模板生成, 就意味着前端开发人员要接触后端的模板,需要前端人员提供他们做好的HTML, 交给后端人员,再由后端人员把它修改成Django模板,这样会有很多问题
问题
1、不利于前后端开发任务的分离,前后端开发人员要做额外的沟通。
2、如果前端除了web浏览器,还有手机APP的话, APP 不需要服务端返回HTML, 就得再开发一套数据接口
3、渲染任务在后端执行,大大的增加了后端的性能压力。
4、尤其是有的HTML页面很大, 当有大量的用户并发访问的时候, 后端渲染工作量很大,很耗费CPU 资源。
现在随着 浏览器中javascript 解释器性能的突飞猛进,以及一些前端模板库和框架的流行。很多架构师将 页面的html 内容生成 的任务放到前端,这样 服务端就只负责提供数据, 界面的构成全部在前端(浏览器前端或者手机前端)进行,称之为前端渲染。
1、需要django返回的数据都是动态的,比如用户信息,药品信息,订单信息,等等
这些数据都是通过去数据库查询而获取到的,
2、静态数据,比如页面HTML文档、css文档、图片、视频这些数据不应该由django去返回的
这些数据通常都是由其他的 静态资源服务软件,比如 Nginx、Varnish等等返回给前端
这些软件都会有效的对静态数据进行缓存,大大提高服务效率