Django中ORM介绍及数据库的的增删改查

目录

一、ORM (对象关系映射 Object Relational Mapping)

二、表结构的创建和修改

1、表结构的创建

1-1 setting内建立数据库连接

1-2 models.py 内创建模型

1-3 migrations 内 init.py文件修改

1-4 迁移命令的两种执行方式

2、表结构的修改

2-1 增加字段

2-2 删除字段

2-3 修改字段

3、模型内字段类型

4、字段参数

5、元信息

三、单表记录操作

1、在py文件中调用Django环境(可用于orm记录操作语言的测试)

2、查(API)

  • filter() - 返回queryset对象

  • 基于filter的双下划线模糊查询

  • values(*field):返回特殊的queryset类型

3、增(两种方式)

方式一、create方法创建记录对象

方式二、创建对象,save方法保存

4、改(两种方式)

1、方式一:update()方法

2、方式二、修改对象,save 保存

5、删(delete())

1、所有对象删除

2、根据记录删除

一、ORM (对象关系映射 Object Relational Mapping)
介绍:对pymysql模块的二次封装,进行操作mysql

优点:

提高了开发效率
可以使用代码创建表、并对表进行增删改查操作
缺点:

降低了执行效率
不可以自主创造数据库

二、表结构的创建和修改

1、表结构的创建
1-1 setting内建立数据库连接
DATABASES = {
‘default’: {
‘ENGINE’: ‘django.db.backends.mysql’,
‘NAME’: ‘lqz’,
‘USER’: ‘root’,
‘PASSWORD’: ‘123456’,
‘HOST’: ‘127.0.0.1’,
‘PORT’: 3306,
‘ATOMIC_REQUEST’: True,
‘OPTIONS’: {
“init_command”: “SET storage_engine=MyISAM”,
}
}
}

‘’’
‘NAME’:要连接的数据库,连接前需要创建好
‘USER’:连接数据库的用户名
‘PASSWORD’:连接数据库的密码
‘HOST’:连接主机,默认本机
‘PORT’:端口 默认3306
‘ATOMIC_REQUEST’: True,
设置为True统一个http请求对应的所有sql都放在一个事务中执行(要么所有都成功,要么所有都失败)。
是全局性的配置, 如果要对某个http请求放水(然后自定义事务),可以用non_atomic_requests修饰器
‘OPTIONS’: {
“init_command”: “SET storage_engine=MyISAM”,
}
设置创建表的存储引擎为MyISAM,INNODB
‘’’
1-2 models.py 内创建模型
from django.db import models

一个类就是一个表

class User(models.Model):
# 自增int类型,是主键
id = models.AutoField(primary_key=True)
# name 是一个varchar类型,长度是32
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
1-3 项目 内 init.py文件修改
注意:

若只是在app文件夹下的init文件添加,则只能当前app内使用mysqldb
若在总项目文件夹下的init文件中添加,所有app的数据库都使用mysqldb
import pymysql
pymysql.install_as_MySQLdb()
1-4 迁移命令的两种执行方式
 方式一、终端命令
python3 manage.py makemigrations  — 记录数据库的修改记录
python3 manage.py migrate ---- 数据修改同步数据库
方式二、pycharm工具栏操作
工具栏 – tools—>Run manage.py Task
makemigrations
migrate
注意:
     1 数据库迁移记录都在 app01下的migrations里
        2 使用showmigrations命令可以查看没有执行migrate的文件(python manage.py showmigrations)
        3  makemigrations是生成一个文件,migrate是将更改提交到数据量

2、表结构的修改
2-1 增加字段
from django.db import models

一个类就是一个表

class User(models.Model):
# 自增int类型,是主键
id = models.AutoField(primary_key=True)
# name 是一个varchar类型,长度是32
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)

# 在原有结构上添加字段,必须带有默认值
phone=models.CharField(max_length=64,default='120')

2-2 删除字段
from django.db import models

一个类就是一个表

class User(models.Model):
# 自增int类型,是主键
id = models.AutoField(primary_key=True)
# name 是一个varchar类型,长度是32
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)

# 在原有结构上注释字段
# phone=models.CharField(max_length=64,default='120')

‘’’ 文件修改完成,执行两句迁移命令 ‘’’
2-3 修改字段
from django.db import models

一个类就是一个表

class User(models.Model):
# 自增int类型,是主键
id = models.AutoField(primary_key=True)
# name 是一个varchar类型,长度是32
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)

# 在原有结构上修改结构内容
phone=models.CharField(max_length=64,default='11111111111')

‘’’ 文件修改完成,执行两句迁移命令 ‘’’
 
3、模型内字段类型
AutoField(Field) - int自增列,必须填入参数 primary_key=True
BigAutoField(AutoField) - bigint自增列,必须填入参数 primary_key=True
//注:当model中如果没有自增列,则自动会创建一个列名为id的列
from django.db import models

class UserInfo(models.Model):
# 自动创建一个列名为id的且为自增的整数列
username = models.CharField(max_length=32)

class Group(models.Model):
# 自定义自增列
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)

mallIntegerField(IntegerField): - 小整数 -32768 ~ 32767

PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正小整数 0 ~ 32767

IntegerField(Field) - 整数列(有符号的) -2147483648 ~ 2147483647

PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正整数 0 ~ 2147483647

BigIntegerField(IntegerField): - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807

//自定义无符号整数字段

class UnsignedIntegerField(models.IntegerField):
def db_type(self, connection):
return ‘integer UNSIGNED’

‘’’
PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
‘AutoField’: ‘integer AUTO_INCREMENT’,
‘BigAutoField’: ‘bigint AUTO_INCREMENT’,
‘BinaryField’: ‘longblob’,
‘BooleanField’: ‘bool’,
‘CharField’: ‘varchar(%(max_length)s)’,
‘CommaSeparatedIntegerField’: ‘varchar(%(max_length)s)’,
‘DateField’: ‘date’,
‘DateTimeField’: ‘datetime’,
‘DecimalField’: ‘numeric(%(max_digits)s, %(decimal_places)s)’,
‘DurationField’: ‘bigint’,
‘FileField’: ‘varchar(%(max_length)s)’,
‘FilePathField’: ‘varchar(%(max_length)s)’,
‘FloatField’: ‘double precision’,
‘IntegerField’: ‘integer’,
‘BigIntegerField’: ‘bigint’,
‘IPAddressField’: ‘char(15)’,
‘GenericIPAddressField’: ‘char(39)’,
‘NullBooleanField’: ‘bool’,
‘OneToOneField’: ‘integer’,
‘PositiveIntegerField’: ‘integer UNSIGNED’,
‘PositiveSmallIntegerField’: ‘smallint UNSIGNED’,
‘SlugField’: ‘varchar(%(max_length)s)’,
‘SmallIntegerField’: ‘smallint’,
‘TextField’: ‘longtext’,
‘TimeField’: ‘time’,
‘UUIDField’: ‘char(32)’,
‘’’

BooleanField(Field) - 布尔值类型

NullBooleanField(Field): - 可以为空的布尔值

CharField(Field) - 字符类型 - 必须提供max_length参数, max_length表示字符长度

TextField(Field) - 文本类型

EmailField(CharField): - 字符串类型,Django Admin以及ModelForm中提供验证机制

IPAddressField(Field) - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制

GenericIPAddressField(Field) - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
  - 参数:
     protocol,用于指定Ipv4或Ipv6, ‘both’,“ipv4”,“ipv6”
     unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要 protocol=“both”

URLField(CharField) - 字符串类型,Django Admin以及ModelForm中提供验证 URL

SlugField(CharField) - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)

CommaSeparatedIntegerField(CharField) - 字符串类型,格式必须为逗号分割的数字

UUIDField(Field) - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证

FilePathField(Field) - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能

  • 参数:
    path,                      文件夹路径
    match=None,                正则匹配
    recursive=False,           递归下面的文件夹
    allow_files=True,          允许文件
    allow_folders=False,       允许文件夹

FileField(Field) - 字符串,路径保存在数据库,文件上传到指定目录

  • 参数:
    upload_to = “”      上传文件的保存路径
    storage = None      存储组件,默认django.core.files.storage.FileSystemStorage

ImageField(FileField) - 字符串,路径保存在数据库,文件上传到指定目录

  • 参数:
    upload_to = “”      上传文件的保存路径
    storage = None      存储组件,默认
               django.core.files.storage.FileSystemStorage
    width_field=None,   上传图片的高度保存的数据库字段名(字符串)
    height_field=None   上传图片的宽度保存的数据库字段名(字符串)

DateTimeField(DateField) - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]

DateField(DateTimeCheckMixin, Field) - 日期格式      YYYY-MM-DD

TimeField(DateTimeCheckMixin, Field) - 时间格式      HH:MM[:ss[.uuuuuu]]

DurationField(Field) - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型

FloatField(Field) - 浮点型

DecimalField(Field) - 10进制小数

  • 参数:
    max_digits,小数总长度
    decimal_places,小数位长度

BinaryField(Field) - 二进制类型

4、字段参数
(0) null 如果为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False.
(1) blank 如果为True,该字段允许不填。默认为False。 要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。 如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。
(2) default 字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用。
(3) primary_key 如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True, Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为, 否则没必要设置任何一个字段的primary_key=True。
(4) unique 如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的
(5) choices 由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,
而且这个选择框的选项就是choices 中的选项。
 
5、元信息
class UserInfo(models.Model):
nid = models.AutoField(primary_key=True)
username = models.CharField(max_length=32)
class Meta:
# 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
db_table = “table_name”

        # 联合索引
        index_together = [
            ("pub_date", "deadline"),
        ]

        # 联合唯一索引
        unique_together = (("driver", "restaurant"),)

        # admin中显示的表名称
        verbose_name

        # verbose_name加s
        verbose_name_plural

三、单表记录操作

1、在py文件中调用Django环境(可用于orm记录操作语言的测试)
import os

if name == ‘main’:
os.environ.setdefault(“DJANGO_SETTINGS_MODULE”, “day76orm.settings”)
import django

django.setup()

from app01 import models

# 记录的操作
book=models.Book.objects.create(name='红楼梦',price=23.8,publish='人民出版社',author='曹雪芹',create_data='2018-09-17')
print(book.name)

…… ……

2、查(API)
总结:

python数据精度存在盲点,使用查询数字类型的时候,注意转换的sql语句所传输的数字是否精确
可以对queryset对象使用.query方法调用,可以查询最终传输到数据的纯生sql语句
查询得到的queryset可以进行后续的查询方法,通过.进行调用
all()  - models.User.objects.all() 查询所有结果,得到的是一个queryset对象(列表),列表内存储对象。
filter(**kwargs)
  – models.User.objects.filter(name=‘红楼梦’).first()

包含与所给筛选条件匹配的对象,返回queryset对象
get(**kwargs)

– models.User.objects.get(name=‘红楼梦’)

返回筛选条件匹配的对象,且返回结果有且只有一个;若存在符合对象超过一个或者不存在,抛出异常
exclude(*field)

– models.User.objects.exclude(name=‘红楼梦’)

包含了所有与筛选条件不匹配的对象,返回queryset对象
order_by(*field)

– models.User.objects.all.order_by(‘id’)

– models.User.objects.all.order_by(’-id’,‘name’)

对查询结果排序 (’-id’),默认升序,加- 降序。多个过滤条件可以同时共用,返回queryset对象
reverse()

– models.User.objects.all().reverse()

对查询结果反向排序,返回queryset对象
count()

– models.User.objects.all().count()

queryset为调用对象,返回数据库中匹配查询(QuerySet)的对象数量
first()

- models.User.objects.first()

返回第一条记录
last()

-models.User.objects.last()

返回最后一条记录
exists() 若queryset包含数据,返回True,否则False,返回布尔类型
values(*field)

– models.User.objects.all().values(‘name’)

返回一个ValueQuerySet - 一个特殊的QuerySet,运行后得到一个可迭代的字典序列

values_list(*field)

– models.User.objects.all().values_list(‘name’,‘id’)

同values()相似,返回一个元组列表

distinct()

– models.User.objects.all().distinct()

– models.Book.objects.all().values(‘name’).distinct()

从返回的结果中剔除重复记录;distinct seletc * 的时候没有意义,只要存在唯一的字段(id段等)都没有去重意义

  • filter() - 返回queryset对象

查询名字叫西游记的这本书,返回单个对象

ret = models.Book.objects.filter(name=‘西游记’).first()
print(ret)
print(type(ret))

支持类列表的查询方式

ret = models.Book.objects.filter(name=‘西游记’)[1]

类列表的查询方式,不支持负数,只支持正数

ret = models.Book.objects.filter(name=‘西游记’)[-1]

filter内可以传多个参数,用逗号分隔,他们之间是and的关系

返回queryset

价格使用字符串,防止精度不准确,导致无法进行查询

ret = models.Book.objects.filter(name=‘西游记’, price=‘73.8’)
print(ret)
print(type(ret))

ret.query -->queryset对象打印sql

print(ret.query)

‘’’
SELECT
app01_book.id,
app01_book.name,
app01_book.price,
app01_book.publish,
app01_book.author,
app01_book.create_data
FROM
app01_book
WHERE
(
app01_book.name = 西游记
AND app01_book.price = 73.8
)
‘’’

  • 基于filter的双下划线模糊查询

filter(字段名__gt=’’) ---- 大于

查询价格大于89 的书

ret=models.Book.objects.filter(price__gt=‘89’)

filter(字段名__lt=’’) ---- 小于

查询价格小于89 的书

ret=models.Book.objects.filter(price__lt=‘89’)

ret=models.Book.objects.filter(price__lt=‘89’,price=‘89’) — 错误的小于等于

filter(字段名__lte=’’) ---- 小于等于

ret=models.Book.objects.filter(price__lte=‘89’)

filter(字段名__gte=’’) ---- 大于等于

ret = models.Book.objects.filter(price__gte=‘89’)

filter(字段名__in=’’) ---- 字段存在列表中

ret=models.Book.objects.filter(price__in=[‘23.8’,‘89’,‘100’])

filter(字段名__range=’’) ---- 字段数据在范围内(between and)

ret=models.Book.objects.filter(price__range=[50,100])

filter(字段名__contains=’’) ---- 字段数据包含内容 模糊查询 like % %

查询名字有’%红%'的书

ret=models.Book.objects.filter(name__contains=‘红’)

filter(字段名__icontains=’’) ---- 字段数据包含内容,并且忽略大小写 模糊查询 like % %

查询名字带p的书,忽略大小写

ret=models.Book.objects.filter(name__icontains=‘P’)

filter(字段名__startswith=’’) ---- 字段数据以内容开头

ret=models.Book.objects.filter(name__startswith=‘红’)

filter(字段名__endswith=’’) ---- 字段数据以内容结尾

ret=models.Book.objects.filter(name__endswith=‘梦’)

filter(字段名__year=’’) ---- 查询字段内容以指定年份查询

ret=models.Book.objects.filter(create_data__year=‘2018’)

filter(字段名__month=’’) ---- 查询字段内容以指定月份查询

ret = models.Book.objects.filter(create_data__month=‘9’)

filter(字段名__day=’’) ---- 查询字段内容以指定日期查询

ret = models.Book.objects.filter(create_data__day=‘8’)

  • values(*field):返回特殊的queryset类型

values(*field): queryset对象里套字典

ret=models.Book.objects.all().values(‘name’,‘price’)

print(ret)

print(ret[1])

{‘name’: ‘水浒传’}

print(ret.query)
‘’’
SELECT
app01_book.name,
app01_book.price
FROM
app01_book
‘’’

ret=models.Book.objects.all().values(‘name’)

print(ret)

print(ret[1])

{‘name’: ‘水浒传’}

print(ret.query)
‘’’
SELECT
app01_book.name
FROM
app01_book
‘’’
 
3、增(两种方式)

方式一、create方法创建记录对象
name=request.POST.get(‘name’)
pwd=request.POST.get(‘password’)
addr=request.POST.get(‘addr’)
user=models.User.objects.create(name=name,password=pwd,address=addr)
方式二、创建对象,save方法保存
name=request.POST.get(‘name’)
pwd=request.POST.get(‘password’)
addr=request.POST.get(‘addr’)
user=models.User(name=name,password=pwd,address=addr)
user.save()
4、改(两种方式)

1、方式一:update()方法
注意:update方法对于任何结果集(queryset)有效,可以同时更新多条记录,使用update()方法会返回一个整数数值,表示受影响的记录条数。

name=request.POST.get(‘name’)
pwd=request.POST.get(‘password’)
addr=request.POST.get(‘addr’)
models.User.objects.filter(id=id).update(name=name,password=pwd,address=addr)
2、方式二、修改对象,save 保存
book = models.Book.objects.filter(name=‘西游记’).first()
book.price=89
book.save()
 
5、删(delete())
1、所有对象删除
models.User.objects.all().delete()
2、根据记录删除
id = request.GET.get(‘id’)
ret = models.User.objects.filter(id=id).delete()

ret = models.Book.objects.filter(name=‘西游记’).first()

你可能感兴趣的:(Django,Django,pyhton)