首页 > 数据库 >Django模型(数据库)

Django模型(数据库)

时间:2023-03-16 16:34:27浏览次数:44  
标签:name models 数据库 Django filter objects Student django 模型

Django模型

Django对各种数据库提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。Django为这些数据库提供了统一的调用API,可按需选择不同数据库。

Django模型使用自带的ORM(对象关系映射Object Relational Mapping)用于实现面向对象编程语言里不同类型系统的数据之间的转换。

ORM

ORM 在业务逻辑层和数据库层之间充当了桥梁的作用。ORM 是通过使用描述对象和数据库之间的映射的元数据,将程序中的对象自动持久化到数据库中。

ORM解析过程:

  1. ORM将Python代码转换成SQL语句
  2. SQL语句通过pymysql传送到数据库服务端
  3. 在数据库中执行SQL语句并将结果返回
  • 使用ORM优点:提高开发效率、不同数据库可以平滑切换。
  • 使用ORM缺点:ORM代码转换为SQL语句时,需花费一定时间,执行效率会有所降低; 长期写ORM代码,会降低编写SQL语句的能力。

类实例 ---------> 表中的一条记录

然后通过对类,类属性,类实例的各种操作,达到操作数据库的功能,底层是生成原生的sql进行数据操作。

安装数据库

创建数据库的docker命令

docker run --name ck10_mariadb --restart=always -d -v ck10_mariadb:/var/lib/mysql -e MARIADB_ROOT_PASSWORD=pythonvip -p 4002:3306 -e MARIADB_DATABASE=lemontest mariadb:latest

django配置数据库

安装驱动

mysql,mariadb,django官方推荐的驱动程序mysqlclient

windows环境

在网站https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient下载与python版本对应的mysqlclient本地安装文件,再使用pip命令安装,例如:

pip install mysqlclient‑1.4.6‑cp38‑cp38‑win_amd64.whl  # py3.8 64位

mac环境

依赖mysql客户端

$ brew install mysql-client
$ echo 'export PATH="/usr/local/opt/mysql-client/bin:$PATH"' >> ~/.bash_profile
$ source .bash_profile
$ pip install mysqlclient

Linux环境

linux环境下需要对应的依赖,根据环境不同依赖有所不同,下面的只是基本的步骤,不能保证在所有的环境上都有效。

Debian/Ubuntu

$ sudo apt-get install python3-dev default-libmysqlclient-dev build-essential
$ pip install mysqlclient

Red Hat /CentOS

sudo yum install python3-devel mysql-devel
pip install mysqlclient

连接配置

在settings.py中修改如下配置:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'lemontest',
        'USER': 'root',
        'PASSWORD': 'pythonvip',
        'HOST': 'www.hhxpython.com',
        'PORT': '4002'
    }
}

模型

django中的模型准确且唯一的描述了数据。它包含存储数据的重要的字段和行为。一般来说,每一个模型都映射一个张数据库表。

基础:

  • 每个模型都是一个python的类,这些类都要继承django.db.models.Model
  • 模型类的每个属性都相当于数据库的一个字段
  • 利用这些,Django提供了一个自动生成访问数据库的API

创建模型

设计一张学生表tb_student,表结构如下:

id int not null auto_increment primarykey
name varchar(20) not null
age tinyint default null
sex tinyint default null
qq varchar(20) default null unique
phone varchar(20) defautl null unique
c_time datetime not null

跟视图一样,django中模型一般定义在应用目录下的models.py模块下:

from django.db import models

class Student(models.Model): # 必须继承
    name = models.CharField('姓名', max_length=20, help_text='姓名')
    age = models.SmallIntegerField('年龄', null=True, blank=True, help_text='年龄')
    sex = models.SmallIntegerField('性别', default=1, help_text='性别')
    qq = models.CharField('qq号码', max_length=20, null=True, blank=True, unique=True, help_text='qq号码')
    phone = models.CharField('手机号码', max_length=20, null=True, blank=True, unique=True, help_text='手机号码')
    c_time = models.DateTimeField('创建时间', auto_now_add=True)
    
    #模型类里面输出字段,如果是int类型的要加str(),不然查询后获取会报错
    def __str__(self):
        """定义每个数据对象的显示信息"""
        return str(self.name)
    class Meta:
        db_table = 'tb_student'   # 设置创建表示的表名
        verbose_name = '学生信息'
        verbose_name_plural = verbose_name  # django admin中显示模型的说明

表的字段类型和字段参数

每一个字段由一个字段类的实例表示。每个字段实例的名称,类属性名,就是字段的名称,数据库也会以它为列名。

字段类型:

  1. models.AutoField 自增列=int(11) 如果没有的话,默认会生成一个名称为id的列,如果要显示为一个自定义自增列,必须将列设置为主键 primary_key=True
  2. models.CharField 字符串字段,必须给max_length参数
  3. models.TextField 字符串=longtext
  4. models.BlooleanField 布尔型字段=tinyint(1) 不能为空,blank=True
  5. models.NullBooleanField 允许为空的布尔类型
  6. models.CommaSeparatedIntegerField 用逗号分割的数字=varchar。继承CharField,所以必须给max_length参数
  7. models.DateField 日期类型date,参数:auto_now=True则每次都会更新这个时间;auto_now_add=True则是第一次创建添加,之后的更新不会改变
  8. models.DateTimeField 日期类型datetime,同DateField的参数
  9. models.TimeField 时间 HH:MM:[ss[.uuuuuu]]
  10. models.EmailField 字符串类型(正则表达式邮箱)=varchar 对字符串进行正则表达式
  11. models.URLField 字符串,地址正则表达式
  12. models.FloatField 浮点类型=double
  13. models.IntegerField 整型(-2147483648,2147483647)
  14. models.BigIntegerField 长整型(-9223372036854775808, 9223372036854775807)
  15. models.SmallIntegerField 数字(-32768,32767) 数据库中的字段有:tinyint、smallint、int、bigint
  16. models.PositiveIntegerField 正Integer(0,32767)
  17. models.PositiveSmallIntegerField 正smallInteger(0, 2147483647)
  18. models.SlugField 减号、下划线、字母、数字
  19. models.IPAddressField 字符串类型(ip4正则表达式)
  20. models.GenericIPAddressField 字符串类型(ip4和ip6是可选的)。参数:protocol可以是:'both' 'ipv4' 'ipv6' 验证时会根据设置报错
  21. models.DecimalField 十进制小数类型=decimal。必须指定整数位max_digits和小数位decimal_places
  22. models.BinaryField 二进制
  23. models.ImageField 图片
  24. models.FileField 文件

字段参数:

  1. null=True 数据库中字段是否可以为空

  2. blank=True django的Admin中添加数据时是否可以允许空值

  3. primary_key=False 主键,对AutoField设置主键后,就会代替原来的自增id列

  4. auto_now=True 自动创建—无论添加或修改,都是当前操作时间

  5. auto_now_add=True 自动创建—永远是创建时的时间

  6. choice

    选项框,定义一个元组变量,参数值取该变量

    GENDER_CHOICE = ((u'M',u'Male'),(u'F',u'Female'))
    gender= models.BigIntegerField(choices=GENDER_CHOICE)
    
  7. max_length

  8. default 默认值

  9. verbose_name Admin中字段的现实名称

  10. db_column 数据库中的字段名称

  11. unique=True 不允许重复

  12. db_index=True 数据库索引

  13. editable=True 在Admin里是否可编辑

  14. error_messages=None 错误提示

  15. auto_created=False 自动创建

  16. help_text 在Admin中提示帮助信息

  17. validators=[]

  18. upload-to

自主设置 主键primary_key 例子:

django的models新增数据库表时,如果不设置主键,会默认新增一个id为主键,想自己设置一个字段为主键,需加个参数primary_key=True

from django.db import models
#新增产品表,设置产品名称为主键,让产品名不重复
class Prouct(models.Model):
    product_name = models.CharField(max_length=20,primary_key=True)
    person_email = models.EmailField(max_length=30)

激活模型

安装应用

把应用添加到项目中,在配置文件中设置:

INSTALLED_APPS = [
	...
    'crm.apps.CrmConfig'
]

生成迁移记录

在命令行运行如下命令:

python manage.py makemigrations crm

会在应用的migrations目录下生成迁移记录文件。

通过运行makemigrations命令,django会检测你对模型文件的修改(修改了模型,修改了字段),并把修改的部分存储为一次迁移。

数据迁移

django有一个自动执行数据库迁移并同步管理数据库结构的命令migrate

通过命令sqlmigrate可以看到你要迁移的sql。

python manage.py sqlmigrate crm 0001

那么就会输出对应迁移文件要执行的sql。

运行命令

python manage.py migrate 

第一次迁移时,django会在数据库中创建一个特殊的表django_migrations用来记录和跟踪执行过哪些迁移。

改变模型的时候需要三步:

  1. 编辑models.py文件,改变模型
  2. 运行python mange.py makemigrations 为模型的改变生成迁移文件
  3. 运行python mange.py migrate 应用数据库迁移

数据库操作

django会自动给予一条数据库抽象API。

为了方便调试,我们通过下面的命令进入交互式python命令行:

python mange.py shell

这个命令会导入当前项目的django环境。

默认的python解释器,没有补全和高亮功能,推荐安装ipython

pip install ipython

新增数据

from django.http import HttpResponse
from models import Student
# 数据库操作
def add_user(request):
    test1 = Student(name='叶凡' ,age=1000)
    test1.save()
    return HttpResponse("数据库Student用户添加成功")

查询数据

  • 通过objects这个模型管理器的 all() 获取所有数据行,相当于SQL中的select * from

    a = Student.objects.all()
    
  • filter() 相当于SQL中的where,可设置条件过滤结果, 结果为list

    b = Student.objects.filter(name='小明')
    
  • get() 获取单个对象

    c = Student.objects.get(name='小兰')
    
  • 索引 限制返回的数据,相当于SQL中的offset 0 limit 2; 如下返回2条

    d = Student.objects.order_by('name')[0:2]
    
  • order_by()查询结果排序

     e = Student.objects.order_by('id')
    
  • 上面的方法可以连着使用

    d = Student.objects.filter(name='小红').order_by('id')[0:2]
    

更新数据

from django.http import HttpResponse
from models import Student
# 更新数据方法
def update_user(request):
    # 方法一:通过objects模型管理器的get()获取指定数据行,修改再save,相当于SQL中的update
    test2 = Student.objects.get(name='无始')
    test2.age = '120000'
    test2.save()
    # 方法二:通过objects模型管理器的filter()获取id=2的数据行,再update指定字段
    Student.objects.filter(id=2).update(age='3000')
    # 修改所有行: 通过objects模型管理器的all()获得所有数据行,相当于SQL中的SELECT * FROM, 
    Student.objects.all().update(age='100')
    return HttpResponse("<p>年龄修改成功</p>")

删除数据

from django.http import HttpResponse
from models import Student
# 更新数据方法
def delete_user(request):
    # 方法一:通过objects模型管理器的get()获取name='小凡'的数据行,再delete该行
    test3 = Student.objects.get(name='小凡')
    test3.delete()
    # 方法二:通过objects模型管理器的filter()获取id=1的数据行,再delete该行
    Student.objects.filter(id=1).delete()
    # 删除所有数据:通过objects模型管理器的all()获取所有数据行,再delete
    Student.objects.all().delete()
    return HttpResponse("<p>数据删除成功</p>")

查询表结果详解

django查询数据库的方法很多,不同的方法返回的结果也不太一样,以下13个查询方法:

  • 返回对象是对象列表的:all() filter() exclude() order_by() reverse() values() values_list() distince()
  • 返回结果是对象的:get() first() last()
  • 返回结果是布尔值的:exists()
  • 返回结果是数字的:count()

准备数据(之前的Student**表)

get() 从数据看取得唯一一个匹配的结果,返回一个对象。调用者是objects管理器,返回查询到model对象(查询结果有且只有一个才执行)。

查询结果有多个,会报错MultipleObjectsReturned,如果查询结果有0个,会报错DoesNotExist。

    r = Student.objects.get(name='叶凡').age()
    ret = Student.objects.get(name='叶凡')
    r = ret.name + str(ret.age)

first() 和 last() 返回第一条记录和返回最后一条记录,返回的是一个对象。调用者是queryset,返回model对象

    #同 fir = Student.objects.all().orderby('age')[0]
    fir = Student.objects.all().order_by("age").first()
    f = fir.age
    fir = Student.objects.all().order_by("age").first().age
    las = Student.objects.all().order_by("age").last().age

exists() 如果queryset包含数据,就返回True,否则返回False。调用者是queryset,返回布尔值

    is_exist = Student.objects.all().exists()

count() 数数,由queryset对象调用,返回int

    ret = Student.objects.all().count()

可迭代对象queryset all()

查询整张表sql:select * from Student;

django里查询数据库不需写sql语句,而是objects模型管理器,ret=Student.objects.all() 返回的是整个表的内容,这里返回的是可迭代对象queryset,要取出数据,需要用for循环读取。

from django.http import HttpResponse
from helloApp.models import Student
def select_all(request):
    ids,names,ages = '',"",""
    ret = Student.objects.all()
    for i in ret:
        ids += " " + str(i.id)
        names += " " + i.name
        ages += " " + str(i.age)
    return HttpResponse("<p>查询id结果:%s</p><p>查询name结果:%s</p><p>查询age结果:%s</p>"%(ids,names,ages))

筛选条件 filter()

类似SQL中的where语句:select * from Student where id=7 and name='小凡';

filter()查询结果也是可迭代对象,如果只有一个,可以通过下标取值。找不到的时候给个默认值null。

HelloWorld/ HelloWorld /testdb.py setting.py同级

from django.http import HttpResponse
from helloApp.models import Student
def filter_user(request):
    r = ""
    ret = Student.objects.filter(id=7,name='叶凡')
    try:
        r = ret[0].age
    except:
        r = "null"
    return HttpResponse("<p>查询结果:%s</p>" %r)

可迭代的字典序列 values()

all()filter()返回的都是可迭代的queryset序列,平常我们习惯获取字典的对象,可用values()方法获取。

Student.objects.all().values(“id”,”name”) 类似于SQL语句:select id,name from Student

from django.http import HttpResponse
from helloApp.models import Student
def values_user(request):
    r = ''
    ret = Student.objects.all().values("id","name","age")
    for i in ret:
        r += str(i)
    return HttpResponse("<p>查询结果:%s</p>" %r)

其他可迭代对象:

exclude() 它包含了与所给筛选条件不匹配的对象。由objects管理器调用,返回queryset。

    #查找用户名不是“叶凡”的数据:
    ret = Student.objects.exclude(name="叶凡")

order_by() 对查询结果排序。由queryset对象调用,返回值是queryset。默认是降序,在前面加 – 是代表降序。

# 查询所有数据,按age字段排序,默认升序
    ret = Student.objects.all().order_by("age")
    # 查询name='曹雨生'的数据,按age字段降序排序
    ret = Student.objects.filter(name='曹雨生').order_by("-age")

reverse() 对查询结果反向排序。由queryset对象调用,返回值是queryset

    # 查询所有数据,按age排序,默认升序,再反向排序,功能与-age一样
    ret = Student.objects.all().order_by('age').reverse()
    #查询name='曹雨生'的数据,再反向排序 
    ret = Student.objects.filter(name='曹雨生').reverse()

values_list() 和values()差不多,返回是元组。由queryset对象调用,返回值是queryset

    ret = Student.objects.all().values_list("id","name")

distinct() 从返回结果中剔除重复记录。由queryset对象调用,返回值是queryset。 和SQL中的distinct去重一样。

    ret = Student.objects.all().values("id","name","age").distinct()

数据库查询延伸

django对数据库进行条件查询格式:字段名+两个下划线+查询方法。这些查询方法get和filter都可以使用,但get每次返回的值是惟一的否则报错。

  • all 返回全部数据,为queryset对象 Person.objects.all()
  • lt 返回小于目标值的queryset; lte 返回小于等于目标值的queryset。 Person.objects.filter(idlt=5) Person.objects.filter(idlte=5)
  • gt 返回大于目标值的queryset; gte 返回大于等于目标值的queryset。 Person.objects.filter(idgt=4) Person.objects.filter(idgte=4)
  • 包含:contains区分大小写; icontains不区分大小写。 Person.objects.filter(namecontains=’ab’) Person.objects.filter(nameicontains=’ab’)
  • 精确匹配:exact区分大小写;iexact不区分大小写。 Person.objects.filter(nameexact=’Dog’) Person.objects.filter(nameiexact=’Dog’)
  • 起始匹配:startswith区分大小写;istartswith不区分大小写。 Person.objects.filter(namestartswith=’At’) Person.objects.filter(nameistartswith=’At’)
  • 末尾匹配:endswith区分大小写;iendswith不区分大小写。 Person.objects.filter(nameendswith=’by’) Person.objects.filter(nameiendswith=’by’)
  • startswithendswith混合:Person.objects.filter(namestartswith=’A’,nameendswith=’y’)
  • in:同时查找多个符合条件的数据,相当于批量的精确查找。 Person.objects.filter(id__in=[101,102,103])
  • range:取范围内的值(两边都是闭合,两侧包含)只要是包含这个范围内的值否返回。 Person.objects.filter(id__range=[220,290])
  • isnull:返回是空值的数据,True为空,False非空。 Person.objects.filter(idisnull=True) # 返回[] Person.objects.filter(idisnull=False) # 返回非空数据
  • Q:多条件联合查询,使用前需导入Q模块 from django.db.models import Q
q1 = Q(create_time__year__in=[2018,2019])
q2 = Q(create_time__month=2)
blogs = BologModel.objects.filter(q1,q2)

使用Q()传入相应条件,然后把Q传入查询的函数中,可以传多个Q然后进行查询。q1,q2中间是逗号时取交集,中间是 | 时取并集。

标签:name,models,数据库,Django,filter,objects,Student,django,模型
From: https://www.cnblogs.com/chenxdnote/p/17223102.html

相关文章

  • [[email protected]].Elbie后缀勒索软件解密|数据库恢复
    1.后缀[[email protected]].Elbie勒索软件介绍?[[email protected]].Elbie勒索软件是一种恶意软件,该勒索软件是Phobos家族的一部分。它会加密文件以使其无......
  • 用go实现master/worker模型
    packagescheduleimport( "container/list" "context" "fmt" "sync")/**********************************\ Task任务接口\*********************************......
  • redis线程模型-IO多路复用单线程通俗理解
     Redis单线程redis是以socket方式通信,socket服务端可同时接受多个客户端请求连接,也就是说,redis服务同时面对多个redis客户端连接请求,而redis服务本身是单线程运行。 ......
  • Redis之I/O多路复用模型实现原理
    本文内容基于Redis6.0以前的版本编写,因为6.0之后Redis在网络处理这一块采用了多线程模式,但是I/O多路复用的模型还在,变化不大。本文有不当之处,大家轻喷!Redis之I/O......
  • 20212323严文霞--数据库读书笔记一(P3-P18,P31-P33)
    1.1数据库系统概述1.1.1数据库的4个基本概念数据(data)定义:描述事物的符号记录称为数据。数据有多种表现形式,例如数字、文字、图形、图像、音视频等;数据需要进行解......
  • 数据库同步,MongoDB、ES,寻求免费的可写入型的ODBC驱动
    大家好,我们开发的数据库同步软件DBSync,能同步多种数据库,支持增量同步、异构同步。但对于NoSQL的MongoDB,Elasticsearch,一直有个问题:官方的ODBC驱动只能读数据库,不能写数据......
  • 性能测试从零开始实施指南——场景模型篇
    转载:https://www.cnblogs.com/imyalost/p/11415691.html今年跳槽到一家电商企业,性能测试需要从零开始。在性能测试不断推动落地过程中,积累了一些从零开始的经验和教训,自己......
  • spring boot jpa 数据库字段加密存储
     在SpringBootJPA中,可以通过自定义AttributeConverter类来实现数据库字段的加密存储。AttributeConverter是JPA2.1中引入的一个接口,用于在实体属性和数据库列......
  • Django-4
    Django-41.url的路由系统1、url(r'^index/',views.index),url(r'^home/',views.Home.as_view()),2、url(r'^detail-(\d+).html',views.detail),3、url(r'^......
  • 推荐几款三维模型几何纠正处理软件
    PolyWorks:是一款功能强大的三维测量和几何纠正软件,能够对三维模型进行高精度的几何纠正,支持多种三维数据格式,包括点云、三角网格等。Geomagic:是一款专业的三维扫描和几何......