orm介绍
查询数据层次图解:如果操作mysql,ORM是在pymysq之上又进行了一层封装
MVC或者MTV框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动
ORM是“对象-关系-映射”的简称。
单表操作
在创建的名为app01的项目下的models.py文件内创建模型:
from django.db import models
# Create your models here.
class Book(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=32)
price=models.DecimalField(max_digits=6,decimal_places=2)
publish=models.CharField(max_length=32)
author=models.CharField(max_length=32)
create_date=models.DateField(null=True)
def __str__(self):
return '书名:%s,作者:%s,出版社:%s,价格:%s,出版时间:%s'%(self.name,self.author,self.publish,self.price,self.create_date)
字段参数
每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR
数据库字段的大小。还有一些适用于所有字段的通用参数。 这些参数在文档中有详细定义
---字段---
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)
SmallIntegerField(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)
- 二进制类型
---参数---
(1)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 ,默认的表单将是一个选择框而不是标准的文本框,<br>而且这个选择框的选项就是choices 中的选项。
配置
models.py模型创建好后 在settings.py需要进行数据库的配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'day76',
'HOST':'127.0.0.1',
'PORT':3306,
'USER':'root',
'PASSWORD':'admin'
}
}
#'NAME':要连接的数据库,连接前需要创建好,django不会创建数据库
#'USER':连接数据库的用户名
#'PASSWORD':连接数据库的密码
#'HOST':连接主机,默认本机
#'PORT':端口 默认3306
接下来在项目下的_ _ init _ _.py文件内输入
import pymysql
pymysql.install_as_MySQLdb()
最后通过
python manage.py makemigrations
python manage.py migrate
这两条命令即可在数据库内创建表
表的操作
#插入数据的两种方式
# 方式一 :返回结果是一个对象
book=models.Book.objects.create(name='红楼梦',price=23.8,publish='人民出版社',author='曹雪芹',create_data='2018-09-17')
# 方式二:先实例化产生对象,然后调用save方法,保存
book=models.Book(name='水浒传',price=99.8,publish='老男孩出版社',author='施耐庵',create_data='2018-08-08')
book.save()
print(book.name)
# 时间格式,可以传字符串,可以传日期格式
import datetime
ctime = datetime.datetime.now()
book = models.Book.objects.create(name='西游记', price=73.8, publish='北京出版社', author='吴承恩', create_data=ctime)
#删除
# 删除名字叫西游记的这本书
ret=models.Book.objects.filter(name='西游记').delete()
# 删除的第二种方式:
ret = models.Book.objects.filter(name='西游记').first()
ret.delete()
#修改
ret=models.Book.objects.filter(name='西游记').update(price=20.9)
# 对象修改(没有update方法,但是可以用save来修改)
book = models.Book.objects.filter(name='西游记').first()
book.price=89
book.save()
#查询
(1)all()
ret=models.Book.objects.all()
print(ret)
(2)filter()
# 查询名字叫西游记的这本书
ret=models.Book.objects.filter(name='西游记').first()
# 不支持负数,只支持正数
ret=models.Book.objects.filter(name='西游记')[-1]
# filter内可以传多个参数,用逗号分隔,他们之间是and的关系
ret=models.Book.objects.filter(name='西游记',price='73.8')
# ret.query -->queryset对象打印sql
print(ret.query)
# get() 有且只有一个结果,才能用,如果有一个,返回的是对象,不是queryset对象,通常用在,用id查询的情况
ret=models.Book.objects.get(name='红楼梦')
ret=models.Book.objects.get(id=1)
# exclude()查询名字不叫西游记的书,结果也是queryset对象
ret=models.Book.objects.exclude(name='西游记',price='23.8')
#这里是查询 不是书名为西游记并且价格为23.8的书 exclude把括号内的多个条件当成一个整体来进行查询的
# order_by 按价格升序排
ret=models.Book.objects.all().order_by('price')
# queryset对象可以继续 点 方法
ret=models.Book.objects.all().order_by('price').filter(name='西游记')
# 按价格倒序排
ret=models.Book.objects.all().order_by('-price')
# 可以传多个
ret=models.Book.objects.all().order_by('-price','create_data')
# reverse 对结果进行反向排序
ret=models.Book.objects.all().order_by('-price').reverse()
# count 查询结果个数
ret=models.Book.objects.all().count()
ret=models.Book.objects.all().filter(name='西游记').count()
# last 返回book对象
ret=models.Book.objects.all().last()
# exists 返回结果是布尔类型
ret=models.Book.objects.filter(name='三国演义').exists()
# values(*field): queryset对象里套字典
ret=models.Book.objects.all().values('name','price')
ret=models.Book.objects.all().values('name')
# value_list queryset对象里套元组
ret=models.Book.objects.all().values_list('name','price')
# distinct() 必须完全一样,才能去重 只要带了id,去重就没有意义了
ret=models.Book.objects.all().values('name').distinct()
基于双下划綫的模糊查询
# 查询价格大于89 的书
ret=models.Book.objects.filter(price__gt='89')
# 查询价格小于89 的书
ret=models.Book.objects.filter(price__lt='89')
ret=models.Book.objects.filter(price__lt='89',price='89')
# 小于等于
ret=models.Book.objects.filter(price__lte='89')
# 大于等于,
ret = models.Book.objects.filter(price__gte='89')
# in 在XX中
ret=models.Book.objects.filter(price__in=['23.8','89','100'])
# range 在XX范围内 between and
ret=models.Book.objects.filter(price__range=[50,100])
# contains 查询名字有'%红%'的书
ret=models.Book.objects.filter(name__contains='红')
# icontains 查询名字带p的书,忽略大小写
ret=models.Book.objects.filter(name__icontains='P')
# startswith 以XX开头
ret=models.Book.objects.filter(name__startswith='红')
# endswith 以XX结尾
ret=models.Book.objects.filter(name__endswith='梦')
# pub_date__year 按年查询 也有create_data__month create_data__day
ret=models.Book.objects.filter(create_data__year='2017')