目录
一、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中提供读取文件夹下文件的功能
FileField(Field) - 字符串,路径保存在数据库,文件上传到指定目录
ImageField(FileField) - 字符串,路径保存在数据库,文件上传到指定目录
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进制小数
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段等)都没有去重意义
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]
ret = models.Book.objects.filter(name=‘西游记’, price=‘73.8’)
print(ret)
print(type(ret))
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
)
‘’’
ret=models.Book.objects.filter(price__gt=‘89’)
ret=models.Book.objects.filter(price__lt=‘89’)
ret=models.Book.objects.filter(price__lte=‘89’)
ret = models.Book.objects.filter(price__gte=‘89’)
ret=models.Book.objects.filter(price__in=[‘23.8’,‘89’,‘100’])
ret=models.Book.objects.filter(price__range=[50,100])
ret=models.Book.objects.filter(name__contains=‘红’)
ret=models.Book.objects.filter(name__icontains=‘P’)
ret=models.Book.objects.filter(name__startswith=‘红’)
ret=models.Book.objects.filter(name__endswith=‘梦’)
ret=models.Book.objects.filter(create_data__year=‘2018’)
ret = models.Book.objects.filter(create_data__month=‘9’)
ret = models.Book.objects.filter(create_data__day=‘8’)
ret=models.Book.objects.all().values(‘name’,‘price’)
print(ret)
print(ret[1])
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])
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()