Python 框架学习 Django篇 (三) 链接数据库

只要你是做后端开发的,那么就离不开各种数据库,Django框架对各种数据库都非常友好,比如常见的PostgreSQL、MySQL、SQLite、Oracle,django都对他们提供了统一调用api,我们这里主要使用mysql数据库作为演示

 一、ORM机制

ORM机制,又称为对象关系映射,简单来说就是通过定义python文件中的class类,然后通过ORM将python代码转换成sql语句,再通过pymysql库链接到mysql数据库,执行sql语句

 Python 框架学习 Django篇 (三) 链接数据库_第1张图片

 1、ORM 解析过程

1、ORM 会将 Python 代码转成为 SQL 语句。
2、SQL 语句通过 pymysql 传送到数据库服务端。
3、在数据库中执行 SQL 语句并将结果返回。

 2、python代码与sql语句关系图

Python 框架学习 Django篇 (三) 链接数据库_第2张图片

 二、基本使用

1、准备mysql数据库

#部署容器
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机制无法创建数据库级别操作,只能创建表

2、安装pymysql库

pip3 install pymysql
pip3 install cryptography

3、配置django项目指定数据库

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()

4、创建新项目

django-admin startapp paas

Python 框架学习 Django篇 (三) 链接数据库_第3张图片

5、添加数据库表  模型

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字节

6、添加联系数据库表

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',可以指定自定义的应用程序配置类,并且可以在其中定义更多的配置参数和行为。

7、测试model配置并生成更新脚本

#命令大意为 查看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语句

8、运行数据库操作脚本

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

9、查看数据

#登录paas数据库
use paas

#查看paas库下的表
show tables;

#查看表结构
desc paas_paasinfo;

Python 框架学习 Django篇 (三) 链接数据库_第4张图片

如果以后我们修改了Models.py 里面的库表的定义,都需要再次运行 python manage.py makemigrations common 和 python manage.py migrate 命令,使数据库同步该修改结果

三、Django admin页面

Django提供了一个管理员操作界面可以方便的 添加、修改、删除你定义的 model 表数据

1、创建超级用户

python manage.py createsuperuser


#填写
用户         root
邮箱         [email protected]
密码         12345678
再次输入密码  12345678

2、注册应用model

vi Django_demo/paas/admin.py

from django.contrib import admin

# Register your models here.
from .models import PaasInfo

admin.site.register(PaasInfo)

3、访问管理平台

启动服务

python manage.py runserver

访问页面

http://127.0.0.1:8000/admin/

Python 框架学习 Django篇 (三) 链接数据库_第5张图片

4、添加UI

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',
]

5、再次访问

Python 框架学习 Django篇 (三) 链接数据库_第6张图片

6、添加测试数据

Python 框架学习 Django篇 (三) 链接数据库_第7张图片

7、验证

select * from paas_paasinfo;

Python 框架学习 Django篇 (三) 链接数据库_第8张图片

四、数据库读取

我们在上面实现了链接数据库并插入数据,如果我们想要将数据从数据库读取出来,并且打印到页面上,应该怎么操作呢,下面我们尝试实现访问/sales/SelectHost 路径时返回数据库中PaasInfo 表下的所有数据

1、添加子应用下路由文件

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')),
]

添加后就允许子应用添加自己的路由配置了

2、定义视图

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)

3、新增子路由

vi Django_demo/paas/urls.py

from django.urls import path



from .views import listcustomers
urlpatterns = [
    #paas应用上的路由只需要定义自己路由的部分即可
    path('SelectHost/',listcustomers ),

]

4、测试访问

http://127.0.0.1:8000/sales/SelectHost/

Python 框架学习 Django篇 (三) 链接数据库_第9张图片

五、过滤数据

有的时候,我们需要根据过滤条件查询部分客户信息

比如,当用户在浏览器输入 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等样式或功能,我们下面给返回的数据添加一些显示格式

Python 框架学习 Django篇 (三) 链接数据库_第10张图片

1、代码直接生成HTML

html代码本身也是字符串,我们可以把整个html定义到我们程序中的字符串进行接收

vi Django_demo/paas/views.py

from django.http import HttpResponse


from .models import PaasInfo

#添加html模板变量
html_template ='''






    
        
        
        %s
        
        
        
id 姓名 电话号码 地址
''' 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) #模板变量名称 + % + 返回数据的模板

测试

Python 框架学习 Django篇 (三) 链接数据库_第11张图片

我们用一个变量 html_template 存储html模板, 然后 代码中生成html 里面需要插入的表格记录的内容,这个内容是html片段,也就是 html 表格的每行 。

 2、使用html模板

上面我们直接定义在变量中的html并不方便管理  很多后端框架都提供了一种 模板技术, 可以在html 中嵌入编程语言代码片段, 用模板引擎(就是一个专门处理HTML模板的库)来动态的生成HTML代码,Python 中有很多这样的模板引擎 比如 jinja2 、Mako, Django也内置了一个这样的模板引擎,我们这里使用django 去渲染html

from django.http import HttpResponse


from .models import PaasInfo

#添加html模板变量
html_template ='''






    
        

        {% for customer in customers %}
            

            {% for name, value in customer.items %}            
                            
            {% endfor %}
            
            
        {% endfor %}
                
        
id 姓名 电话号码 地址
{{ value }}
''' 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 %}

 3、前后端分离架构

有了模板引擎,对我们后端开发来说,简化了程序员后端生成HTML的任务

但是,通常来说后端开发的核心任务不是开发前端界面,并且大部分后端开发人员对前端界面开发还是不熟悉的,前端页面要是要前端开发去做

如果动态的界面内容都是由后端模板生成, 就意味着前端开发人员要接触后端的模板,需要前端人员提供他们做好的HTML, 交给后端人员,再由后端人员把它修改成Django模板,这样会有很多问题

问题

1、不利于前后端开发任务的分离,前后端开发人员要做额外的沟通。

2、如果前端除了web浏览器,还有手机APP的话, APP 不需要服务端返回HTML, 就得再开发一套数据接口

3、渲染任务在后端执行,大大的增加了后端的性能压力。

4、尤其是有的HTML页面很大, 当有大量的用户并发访问的时候, 后端渲染工作量很大,很耗费CPU 资源。

现在随着 浏览器中javascript 解释器性能的突飞猛进,以及一些前端模板库和框架的流行。很多架构师将 页面的html 内容生成 的任务放到前端,这样 服务端就只负责提供数据, 界面的构成全部在前端(浏览器前端或者手机前端)进行,称之为前端渲染。

 注意

1、需要django返回的数据都是动态的,比如用户信息,药品信息,订单信息,等等
   这些数据都是通过去数据库查询而获取到的,

2、静态数据,比如页面HTML文档、css文档、图片、视频这些数据不应该由django去返回的
    这些数据通常都是由其他的 静态资源服务软件,比如 Nginx、Varnish等等返回给前端
    这些软件都会有效的对静态数据进行缓存,大大提高服务效率

你可能感兴趣的:(Django框架,python,学习,django)