2)Django ORM框架

目录

一 简介

1)作用:

2)Django ORM的模式特征

3)主要使用步骤

二 用法

1  数据库连接

2 创建数据模型

 3 Django ORM 字段

①常用字段类型

 ②常用字段属性

 4 基本数据操作--增删改查

 5 数据操作常用函数

 三 样例1:数据库表操作

1)准备工作

 二)建立路由与视图函数对应关系

 3)编写视图函数

4)employee数据模型的操作

 四 Django ORM跨表操作

1)与外键有关的跨表操作

 2)与多对多键有关的跨表操作

3)与一对一键有关的跨表操作 

五 Django ORM 聚合与分组查询

 1)聚合查询

2)分组查询

​编辑

六 Django ORM 中的F和Q函数

 1)F函数

 2)Q函数


一 简介

1)作用:

ORM意思是对象关系映射,Django ORM描述Django数据模型类和数据库之间的映射关系,通俗来说就是让一个类和一个数据表进行对应,这使得ORM在数据库层和业务逻辑层之间起到了桥梁的作用。

2)Django ORM的模式特征

Django ORM与数据库映射的关系表现为Django中的一个数据模型映射一个数据库表,其基本情况是:类(ajango.db.models.Model)映射到数据库表,类的属性映射为数据库表的字段,类的实例对象则映射为数据行。

3)主要使用步骤

①在项目使用的数据库管理系统中建立数据库

②在项目配置文件settings.py中色湖之数据库的连接字符

③在应用程序的models.py文件中编写继承于models.Model的数据模型

④运行python manage.py makemigrations,   python manage.py migrate 两个命令生成数据库表

⑤使用Django ORM操作数据库表

二 用法

1  数据库连接

首先登录数据库

假设在数据库中创建了test_orm数据库

2)Django ORM框架_第1张图片

 连接数据库时,我没需要在配置文件settings.py中修改DATABASES代码块

2)Django ORM框架_第2张图片

2 创建数据模型

注意:注册应用程序 

models.py中有了代码,它所属的应用程序必须在settings.py的INSTALLED_APPS中注册,直接将应用程序名添加到INSTALLED_APPS列表中即可。例如我所创建的应用程序名为myapp:

2)Django ORM框架_第3张图片

在此创建一个group模型 有两个属性及user和email。在应用程序目录下的models.py文件下输入以下代码,假设在项目中有一个应用程序名称为myapp

from django.db import models

# Create your models here.
#数据模型一定要继承于models.Model
class Group(models.Model):
    #group_name为团体名称,CharField为类型,max_length设置最大字符数
    #verbose_name设置在Django Admin管理后台页面上显示的字段名
    group_name=models.CharField(max_length=32,verbose_name='团体名称')
    #团体备注说明
    group_script=models.CharField(max_length=60,verbose_name='备注')

group_name和group_script可以乘坐模型字段,每个字段在类中表现为一个类属性,根据映射关系,每个类属性映射为一个数据表字段

在命令行终端输入以下命令,在mysql中生成数据表

 在输入第一个命令时,可能会报错

django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
Did you install mysqlclient?

 解决办法:

 需要到你的项目同名的文件夹下的__init__.py文件中添加如下代码
import pymysql
pymysql.install_as_MySQLdb()

 登陆数据库管理系统,可以看到已经生成数据表myapp_group

说明:1)Django生成数据表时,灰吧models.py的类名转换为小写,然后在前面加上应用程序的名称和下划线作为数据表名称如 myapp.group

2)myapp.group数据表中由id,group_name,group_script 等三个字段,多出的id字段是自动添加的

他作为myapp.group数据表的主键使用

查看生成的数据库表

先切换数据库,再输入命令

use test_orm;

desc myapp_group;

2)Django ORM框架_第4张图片

 3 Django ORM 字段

Django ORM 字段在models.py中创建,按照固定格式在数据模型类中建立,主要包括指定字段名的字段类型,字段属性等;

①常用字段类型

例子:代码

group_name=models.CharField(max_length=32,verbose_name='团体名称')

中的CharFiled是字段类型,知名该字段为字符型,括号内是设置字段属性的参数

常用字段类型

 
  

 

 ②常用字段属性

2)Django ORM框架_第5张图片

注意:

verbose_name在Django Admin管理后台是字段显示名称,可理解为字段别名,verbose_name在SQL层面没有具体体现,也就是说加不加verbose_name对数据库中的字段没有影响。

 4 基本数据操作--增删改查

主要通过数据模型的objects属性来提供数据操作的接口

2)Django ORM框架_第6张图片

2)Django ORM框架_第7张图片

2)Django ORM框架_第8张图片

 5 数据操作常用函数

1)以下五个函数的返回值都是QuerySet对象集

提示:

django的QuerySet对象集本质上对应于数据库表的记录集合,QuerySet有一个特性就是惰性,及返回值为QuerySet的函数不会立即去数据库操作数据,当我们用到QuerySet的值时,他才回去数据库中获取数据。

2)Django ORM框架_第9张图片

2)Django ORM框架_第10张图片

 2)以下三个函数返回其他数据类型,可以理解为特殊的QuerySet类型。

 2)Django ORM框架_第11张图片

 三 样例1:数据库表操作

1)准备工作

①先建立一个test_orm项目

django-admin startproject test_orm

使用cd进入该目录

cd test_orm

②输入命令生成一个名称为employee的应用程序

python manage.py startapp employee

③登录Mysql数据库,创建数据库

create database test_orm;

 ④如果没有安装pymysql模块,在命令行终端数如pip install pymysql进行安装

然后再/test_orm/test_orm/_init_.py文件下输入代码,使用pymysql模块来代替Django Mysql客户端模块

import pymysql
pymysql.install_as_MySQLdb()

 ⑤在settings中修改配置

注册app

2)Django ORM框架_第12张图片

 配置数据库

2)Django ORM框架_第13张图片

⑥在employee/models.py中输入数据模型代码

from django.db import models
#在此处
# Create your models here.
class employee(models.Model):#员工数据模型(员工数据表)
    name=models.CharField(max_length=32,verbose_name='姓名') #员工姓名
    email=models.EmailField(verbose_name='邮箱')#员工的邮箱

    dep=models.ForeignKey(to="department",to_field="id",on_delete=models.CASCADE) #员工的部门,外键,形成一对多的关系

    group=models.ManyToManyField(to="group")#员工加入的团体,多对多关系,就是一个员工可以加入多个团体,一个团体有多个员工
    salary=models.DecimalField(max_digits=8,decimal_places=2)#薪水,数值型
    info = models.OneToOneField(to='employeeinfo',on_delete=models.CASCADE,null=True)#员工补充信息,一对一关系
class department(models.Model):# 部让数据模型(部门数据表)
    dep_name=models.CharField(max_length=32,verbose_name='部门名称',unique=True,blank=False)#部门名称
    dep_script=models.CharField(max_length=60,verbose_name='备注',null=True) #部门备注说明

class group(models.Model):#团体数据模型(团体数据表)
    group_name=models.CharField(max_length=32,verbose_name='团体名称',unique=True,blank=False) # 团体名称
    group_script=models.CharField(max_length=60,verbose_name='备注',null=True) #团体备注说明

class employeeinfo(models.Model): #员工补充信息
    phone = models.CharField(max_length=11) #电话号码
    address = models.CharField(max_length=50)#地址

解释:

①以上代码生成四个数据模型

②一个部门可以有多个员工,所以在员工表中建立外键(ForeignKey)dep字段。要注意的是,有外键的是’多‘,外键关联的表是’-‘,也就是有外键的数据库表有多条记录对应外键关联的数据库表的一条记录;数据模型中的外键在数据库表中以是   外键名_id    形式命名字段,例如:数据模型employee中的dep,在数据库表中字段名为dep_id。

③一个员工可以加入多个团体,一个团体可以有多个员工,所以在员工表建立了多对多键(ManyToManyField)group字段

④一个员工对应一条补充信息,所以在员工表中建立一对一键(OneToOneField)info字段,info在数据库表中的字段名为info_id

⑦在mysql的test_orm数据库中生成数据表

第一行命令对数据模型代码进行检查,出错时在命令行返回相关信息

第二行真正建立数据表

 python manage.py makemigrations

 python manage.py migrate

 随机查看一个数据表,例如

 use test_orm;

 desc employee_employee;

 2)Django ORM框架_第14张图片

 二)建立路由与视图函数对应关系

Django是在urls.py中设立路由(URL)与视图函数的对应关系。用户在浏览器地址栏中输入网址,Django通过URL配置关系找到对应函数,这个函数接受请求,运行其中的逻辑代码并生成响应发挥浏览器,从而完后曾以此用户业务访问过程。

在/test_orm/urls.py下输入以下代码:

from django.contrib import admin
#导入URL配置相关的模块
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    #用include()函数把二级配置包含起来
    path('test_orm_old/',include('employee.urls')),
]

说明:

1)include()函数中的参数是一个字符串,这个字符串指定二级URL配置文件的位置,与文件的路径有点相似,只不过用 “."作为分隔符,并且最后的文件名不包含扩展名

2)如果URL配置文件分级,那么在匹配URL时,要把各级配置文件中的URL表达式合并成一个完整的URL表达式进行匹配

在/test_rom/employee 文件夹新建一个urls.py文件

from django.urls import path,include
from employee.views import  * #导入视图中的函数,*代表所有

urlpatterns = [
    path('list_employee_old/',list_employee_old),
    path('add_employee_old/',add_employee_old),
    path('edit_employee_old//',edit_employee_old),
    path('del_employee_old//',delete_employee_old),
    path('add_dep_old/',add_dep_old),
    path('list_dep_old/',list_dep_old),
    path('del_dep_old//',del_dep_old),
    path('edit_dep_old//',edit_dep_old),
    path('add_group_old/',add_group_old),
    path('list_group_old/',list_group_old),
    path('del_group_old//',del_group_old),
    path('edit_group_old//',edit_group_old),
    path('add_employeeinfo_old/', add_employeeinfo_old),#增加一条用户补充信息(employeeinfo表)
    path('list_employeeinfo_old/', list_employeeinfo_old),#用户补充信息列表(employeeinfo表)
    path('del_employeeinfo_old//', del_employeeinfo_old),#删除一条用户补充信息(employeeinfo表)
    path('edit_employeeinfo_old//', edit_employeeinfo_old),#修改一条用户补充信息(employeeinfo表)
]

说明:

①以上代码分别建立了员工,部门,团体,员工补充信息的增删改查配置项。path()的两个参数中一个用来匹配路径,被称作URL表达式,他撇皮网址的方式类似于正则表达式;

另外一个参数是试图函数名,属兔函数在views.py中定义

②我们在配置项中的URL表带始终和视图函数名后都加了_old,因为这是代码的初始版本,旨在讲解Django ORM的内容,没有对页面进行美化,后续有其他的美化

提示:

 3)编写视图函数

在urls.py文件中通过path()建立对应关系后,还需建立相应的视图函数,函数名与path()的第二个参数相同。

打开employee下的views.py文件,编写视图函数:

第一段代码对部门数据表department进行列表查询

from django.shortcuts import render,redirect,HttpResponse
from .models import employee,department,group,employeeinfo
# Create your views here.
#部门数据表的增删改查
def list_dep_old(request):
    dep_list=department.objects.all()
    return render(request,'test_orm_old/list_dep_old.html',{'dep_list':dep_list})

代码说明: 

2)Django ORM框架_第15张图片

 下面是list_dep_old.html文件的代码,存放在/test_orm/templates/test_orm_old文件夹中

提示:注意创建文件夹

2)Django ORM框架_第16张图片




    
    部门列表



部门列表


{% for dep in dep_list %} {% empty %} {% endfor %}
部门名称 备注说明 操作
{{ dep.dep_name }} {{ dep.dep_script }} 删除 修改
无相关记录!

 代码说明:

2)Django ORM框架_第17张图片

 下面测试一下效果,在命令行终端,进入根目录test_orm

python manage.py runserver

 在地址栏输入https://127.0.0.1:8000/test_orm_old/list_dep_old/并回车

 增加部门视图函数add_dep_old()

def add_dep_old(request):
#判断请求方式,如果是POST,说明前端页面要提交数据
    if request.method=='POST':
        dep_name=request.POST.get('dep_name')
        dep_script = request.POST.get('dep_script')
        if dep_name.strip()=='':
            return render(request, 'test_orm_old/add_dep_old.html', {'error_info': '部门名称不能为空!'})
        try:
#用create函数新建一条记录,这条记录会自动保存,不用调用save函数
            p=department.objects.create(dep_name=dep_name,dep_script=dep_script)
#重定向
            return redirect('/test_orm_old/list_dep_old/')
        except Exception as e:
            return render(request, 'test_orm_old/add_dep_old.html',{'error_info':'录入部门名称重复或信息有错误!'})
        finally:
            pass
    return render(request,'test_orm_old/add_dep_old.html')

代码说明:

2)Django ORM框架_第18张图片

 2)Django ORM框架_第19张图片

 add_dep_old.html




    
    增加部门


增加部门


#当单机保存按钮时,向后端发送post请求
#Django安全机制防止csrf {% csrf_token %}
#input标签的name属性必须设置,后端通过name属性取值   

  

{{ error_info }}

2)Django ORM框架_第20张图片

下面是删除部门记录的视图函数,根据传参,获取id字段等于参数值的激励对象爱国,然后删除。视图函数del_dep_old()的第二个参数实在urls.py文件配置项的path函数中定义的

view.py添加

def del_dep_old(request,dep_id):
    dep_object=department.objects.get(id=dep_id)
    dep_object.delete()
    return redirect('/test_orm_old/list_dep_old/')

2)Django ORM框架_第21张图片

def edit_dep_old(request,dep_id):
    if request.method=='POST':
        id=request.POST.get('id')
#获得前端页面提交的数据
        dep_name=request.POST.get('dep_name')
        dep_script=request.POST.get('dep_script')
        dep_object=department.objects.get(id=id)
#给字段赋值
        dep_object.dep_name=dep_name
        dep_object.dep_script=dep_script
      #保存到数据库
        dep_object.save()
        return redirect('/test_orm_old/list_dep_old/')
    else:
        dep_object=department.objects.get(id=dep_id)
        return render(request,'test_orm_old/edit_dep_old.html',{'department':dep_object})

视图函数edit_dep_old通过return render(request,'test_orm_old/edit_dep_old.html',{'department':dep_object})传递参数给edit_dep_old.html文件




    
    修改部门


修改部门


{% csrf_token %}
  

  

{{ error_info }}

代码说明:

2)Django ORM框架_第22张图片

 下面给出group团体数据库增删改查视图函数代码,供参考


#团队增删改查
def list_group_old(request):
    group_list=group.objects.all()
    return render(request,'test_orm_old/list_group_old.html',{'group_list':group_list})

def add_group_old(request):
    if request.method=='POST':
        group_name=request.POST.get('group_name')
        group_script = request.POST.get('group_script')
        if group_name.strip()=='':
            return render(request, 'test_orm_old/add_group.html', {'error_info': '团队名称不能为空!'})
        try:
            group.objects.create(group_name=group_name,group_script=group_script)
            return redirect('/test_orm_old/list_group_old/')
        except Exception as e:
            return render(request, 'test_orm_old/add_group_old.html',{'error_info':'录入团队名称重复或信息有错误!'})
        finally:
            pass
    return render(request, 'test_orm_old/add_group_old.html')

def del_group_old(request,group_id):
    group_object=group.objects.get(id=group_id)
    group_object.delete()
    return redirect('/test_orm_old/list_group_old/')

def edit_group_old(request,group_id):
    if request.method=='POST':
        id=request.POST.get('id')
        group_name=request.POST.get('group_name')
        group_script=request.POST.get('group_script')
        group_object=group.objects.get(id=id)
        group_object.group_name=group_name
        group_object.group_script=group_script
        group_object.save()
        return redirect('/test_orm_old/list_group_old/')
    else:
        group_object=group.objects.get(id=group_id)
        return render(request,'test_orm_old/edit_group_old.html',{'group':group_object})

list_group_old.html




    
    团队列表



团队列表


{% for group in group_list %} {% empty %} {% endfor %}
团队名称 备注说明 操作
{{ group.group_name }} {{ group.group_script }} 删除 修改
无相关记录!

add_group_old.html




    
    增加团队


增加团队


{% csrf_token %}
  

  

{{ error_info }}

edit_group_old.html

#提示

标签中action=“”设置本网页地址对应的视图函数为处理form提交请求的视图




    
    修改团队


修改团队


{% csrf_token %}
  

  

{{ error_info }}

employeeinfo员工补充信息数据表增删改查视图函数代码如下,供参考

employee和employeeinfo量表有一对一关系,实际上相当于一个表分到两个地方,这样的愿意主要是表的字段访问频率不同,因此把访问频率搞得字段放在一个表里,访问低的放在一个表里。

views.py添加:

#employeeinf增删改查
def list_employeeinfo_old(request):#员工补充信息列表
    info_list=employeeinfo.objects.all()
    return render(request,'test_orm_old/list_employeeinfo_old.html',{'info_list':info_list})
def add_employeeinfo_old(request):#增加一条员工补充信息记录
    if request.method=='POST':
        phone=request.POST.get('phone')
        address = request.POST.get('address')
        if phone.strip()=='':
            return render(request, 'test_orm_old/add_employeeinfo_old.html', {'error_info': '电话不能为空!'})
        try:
            employeeinfo.objects.create(phone=phone,address=address)
            return redirect('/test_orm_old/list_employeeinfo_old/')
        except Exception as e:
            return render(request, 'test_orm_old/add_employeeinfo_old.html',{'error_info':'信息有错误!'})
        finally:
            pass
    return render(request, 'test_orm_old/add_employeeinfo_old.html')

def del_employeeinfo_old(request,info_id):#删除一条员工补充信息记录
    info_object=employeeinfo.objects.get(id=info_id)
    info_object.delete()
    return redirect('/test_orm_old/list_employeeinfo_old/')

def edit_employeeinfo_old(request,info_id):#修改一条员工补充信息记录
    if request.method=='POST':
        id=request.POST.get('id')
        phone = request.POST.get('phone')
        address = request.POST.get('address')
        info_object=employeeinfo.objects.get(id=id)
        info_object.phone=phone
        info_object.address=address
        info_object.save()
        return redirect('/test_orm_old/list_employeeinfo_old/')
    else:
        info_object=employeeinfo.objects.get(id=info_id)
        return render(request,'test_orm_old/edit_employeeinfo_old.html',{'info':info_object})

list_employeeinfo_old.html




    
    Title


人员地址电话列表


{% for info in info_list %} {% empty %} {% endfor %}
电话 地址 操作
{{ info.phone }} {{ info.address }} 删除 修改
无相关记录!

add_employeeinfo_old.html




    
    Title


增加用户电话地址


{% csrf_token %}
  

  

{{ error_info }}

edit_employeeinfo_old.html




    
    Title


修改电话地址


{% csrf_token %}
  

  

{{ error_info }}

4)employee数据模型的操作

employee数据模型中有外键,多对多键,一对一键,与其他操作有不同。

以下为员工数据表的删除操作的视图函数

views中添加:

def list_employee_old(request):
    emp=employee.objects.all()
    return render(request,'test_orm_old/list_employee_old.html',{'emp_list':emp})

def delete_employee_old(request,emp_id):
    #取出主键值等于emp_id的记录对象
    emp=employee.objects.get(id=emp_id)
    emp.delete()
    return redirect('/test_orm_old/list_employee_old')

视图函数list_employee_old()取得数据库表中的记录,保存到一个变量中,然后通过

return render(request,'test_orm_old/list_employee_old.html',{'emp_list':emp})将变量传递给list_employee_old.html

ist_employee_old.html:




    
    员工列表


员工列表


{% for emp in emp_list %} {% empty %} {% endfor %}
姓名 邮件 薪水 地址 部门 团队 操作
{{ emp.name }} {{ emp.email }} {{ emp.salary }} {{ emp.info.address }} {{ emp.dep.dep_name }} {% for gp in emp.group.all %} {% if forloop.last %} {{ gp.group_name }} {% else %} {{ gp.group_name }}, {% endif %} {% endfor %} 删除 修改
无相关记录!

2)Django ORM框架_第23张图片

 增加员工记录视图函数的代码如下:

def add_employee_old(request):
    if request.method=="POST":
        name=request.POST.get("name")
        email=request.POST.get("email")
        dep=request.POST.get("dep")
        info = request.POST.get("info")
        salary = request.POST.get("salary")
        #取多个值
        groups=request.POST.getlist("group")
        new_emp=employee.objects.create(name=name,email=email,salary=salary,dep_id=dep,info_id=info)
        #给多对多键字段赋值
        new_emp.group.set(groups)
        return redirect('/test_orm_old/list_employee_old/')
    dep_list=department.objects.all()
    group_list=group.objects.all()
    info_list = employeeinfo.objects.all()

    return render(request,'test_orm_old/add_employee_old.html',{'dep_list':dep_list,'group_list':group_list,'info_list':info_list})

2)Django ORM框架_第24张图片

 视图函数传递变量给add_employee_old.html文件:




    
    Title


增加员工


{% csrf_token %}
  

  

  

 

 

 

2)Django ORM框架_第25张图片

views:

def edit_employee_old(request,emp_id):
    if request.method=="POST":
        id=request.POST.get('id')
        name=request.POST.get("name")
        email=request.POST.get("email")
        dep=request.POST.get("dep")
        info=request.POST.get("info")
        groups=request.POST.getlist("group")
        emp=employee.objects.get(id=id)
        emp.name=name
        emp.email=email
        emp.dep_id=dep
        emp.info_id=info
        emp.group.set(groups)
        emp.save()

        return redirect('/test_orm_old/list_employee_old/')
    emp=employee.objects.get(id=emp_id)
    dep_list = department.objects.all()
    group_list = group.objects.all()
    info_list = employeeinfo.objects.all()
    return render(request, 'test_orm_old/edit_employee_old.html',{'emp':emp,'dep_list':dep_list,'group_list':group_list,'info_list':info_list})

 视图函数edit_employee_old通过render()将变量传递给edit_employee_old.html:




    
    Title


修改员工信息


{% csrf_token %}
  

  

 

 

 

 2)Django ORM框架_第26张图片

 四 Django ORM跨表操作

Django中的数据模型关联关系主要是由外键,多对多键,一对一键形成的关联关系,Django数据模型的实例对象保存着关联关系相关的信息,这样在跨表操作过程中,我们可以根据一个表的记录的信息查询到另一个表的相关联的纪录,充分利用关系型数据库的特点。

1)与外键有关的跨表操作

2)Django ORM框架_第27张图片

 

 

2)Django ORM框架_第28张图片

 2)与多对多键有关的跨表操作

2)Django ORM框架_第29张图片

2)Django ORM框架_第30张图片

 

3)与一对一键有关的跨表操作 

2)Django ORM框架_第31张图片

五 Django ORM 聚合与分组查询

2)Django ORM框架_第32张图片

 1)聚合查询

2)Django ORM框架_第33张图片

 2)Django ORM框架_第34张图片

2)分组查询

2)Django ORM框架_第35张图片

六 Django ORM 中的F和Q函数

 1)F函数

在Django ORM查询语句中,要实现字段值和字段值的比较或者运算操作等就要用到F函数,在F函数中传入字段名九年取得字段的值。

例:

2)Django ORM框架_第36张图片

 2)Q函数

2)Django ORM框架_第37张图片

你可能感兴趣的:(大数据学习,django,python,数据库)