ORM的优势
ORM解决的主要问题是对象和关系的映射。它通常把一个类和一个表一一对应,类的每个实例对应表中的一条记录,类的每个属性对应表中的每个字段。
ORM提供了对数据库的映射,不用直接编写SQL代码,只需像操作对象一样从数据库操作数据。
让软件开发人员专注于业务逻辑的处理,提高了开发效率。
ORM的劣势
ORM的缺点是会在一定程度上牺牲程序的执行效率。
ORM用多了SQL语句就不会写了,关系数据库相关技能退化
Model
在Django中model是你数据的单一、明确的信息来源。它包含了你存储的数据的重要字段和行为。通常,一个模型(model)映射到一个数据库表,
基本情况:
每个模型都是一个Python类,它是django.db.models.Model的子类。
模型的每个属性都代表一个数据库字段。
综上所述,Django为您提供了一个自动生成的数据库访问API,详询 官方文档链接
模型的每个属性都代表一个数据库字段。
综上所述,Django为您提供了一个自动生成的数据库访问API,详询 官方文档链接
ForeignKey(to="Publisher",related_name="xxxx") # 1对多, 外键通常设置在多的那一边
ManyToManyField(to="Book",related_name="xxxx") # 多对多 通常设置在正向查询多的那一边
---------------------------django 模型models 常用字段--------------------------
1、models.AutoField
自增列 = int(1) ,
如果没有的话,默认会生成一个名称为 id 的列
如果要显式的自定义一个自增列,必须设置primary_key=True。
2、models.CharField
字符串字段
必须设置 max_length 参数 max_length表示字符长度
3、models.ForeignKey 外键
publisher = models.ForeignKey(to="Publisher")
4、ManyToManyField 多对多关联
5、models.IntegerField
整数类型
一个整数类型,范围在 -2147483648 to 2147483647
6、models.DateField
日期类型 date
日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例
配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。
配置上auto_now=True,每次更新数据记录的时候会更新该字段
7、EmailField(CharField):
- 字符串类型,Django Admin以及ModelForm中提供验证机制
8、DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度
ORM的字段总结
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
BooleanField(Field)
- 布尔值类型
NullBooleanField(Field):
- 可以为空的布尔值
CharField(Field)
- 字符类型
- 必须提供max_length参数, max_length表示字符长度
TextField(Field)
- 文本类型
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)
- 浮点型
BinaryField(Field)
- 二进制类型
自定义的char类型的字段类
#---------------------------自定义的char类型的字段类---------------------------
class FixedCharField(models.Field):
def __init__(self, max_length, *args, **kwargs):
super().__init__(max_length=max_length, *args, **kwargs)
self.length = max_length
def db_type(self, connection):
"""
限定生成数据库表的字段类型为char,长度为length指定的值
"""
return 'char(%s)' % self.length
class Class(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=25)
# 使用上面自定义的char类型的字段
cname = FixedCharField(max_length=25)
# 效果 有varchar类型和char类型
MySQL [myweb]> desc appweb_class;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(25) | NO | | NULL | |
| cname | char(25) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
ORM的字段参数
null=False 如果是True,Django会在数据库中将此字段的值置为NULL,默认值是False
unique=True 不允许重复
primary_key = False 主键,对AutoField设置主键后,就会代替原来的自增 id 列
max_length 字段长度 max_length=64
db_index = True 数据库索引
default 默认值
auto_now 自动创建---无论添加或修改,都是当前操作的时间
auto_now_add 自动创建---永远是创建时的时间
verbose_name Admin中字段的显示名称,如果不设置该参数时,则与属性名。
db_column 数据库中的字段名称
editable=True 在Admin里是否可编辑
error_messages=None 错误提示
auto_created=False 自动创建
help_text 在Admin中提示帮助信息
validators=[] 验证器
upload-to 文件上传时的保存上传文件的目录
blank 如果为True时django的 Admin中添加数据时可允许空值,可以不填,如果为False则必须填,默认是False。
null纯粹是与数据库有关系的。而blank是与页面必填项验证有关的
choices
一个二维的元组被用作choices,如果这样定义,Django会select box代替普通的文本框,
并且限定choices的值是元组中的值
GENDER_CHOICE = (
(u'M', u'Male'),
(u'F', u'Female'),
)
gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
ORM的练习
from django.db import models
class Userinfo(models.Model):
id = models.AutoField(primary_key=True) #创建一个自增的主键
name = models.CharField(null=False,max_length=20,unique=True) #创建一个varchar(可以保存可变长度的字符串)类型不能为空
def __str__(self):
return "<{} {}>".format(self.id,self.name)
'''
定义如下:代表自定义表名字不加前缀:库中表名就为 userinfo
class Meta:
db_table = "userinfo"
如果不定义 class Meta 库中表名则为 appweb_userinfo
'''
class Publisher(models.Model):
id = models.AutoField(primary_key=True) #创建一个自增的主键
# unique 唯一的不为空的字段
name = models.CharField(null=False,max_length=64,unique=True) #创建一个varchar(可以保存可变长度的字符串)类型不能为空
addr = models.CharField(max_length=128)
def __str__(self):
return "<{} {}>".format(self.id,self.name)
class Book(models.Model):
id = models.AutoField(primary_key=True)#自增的住建
title = models.CharField(max_length=64,null=False,unique=True)
#ForeignKey表示外键
publisher = models.ForeignKey(to="Publisher",on_delete=models.CASCADE,related_name="books")
# 这里创建的字段为publisher_id (Django会自动加_id)所以不用写成publisher_id否者就变成了publisher_id_id
'''
related_name="books" #反向查询的时候可是用books来代替book_set的查询方式
on_delete=models.CASCADE #默认就是这种方式 2.0需要指定
db_constraint=False #不在数据库层建立约束,通过代码控制 默认是True
大数据下不用外键,使用代码约束,使用外键分库分表很难
models.CASCADE 删除关联数据,与之关联也删除
models.DO_NOTHING 删除关联数据,引发错误IntegrityError
models.PROTECT 删除关联数据,引发错误ProtectedError
models.SET_NULL 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
models.SET_DEFAULT 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
publisher = models.ForeignKey(to="Publisher") # 如果出版社被删除、则书籍也被删除
'''
def __str__(self):
# 两种写法
return "Book object :%s" %self.title # 必须返回str
# return "<Book Object: {}>".format(self.title)
class Author(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(null=False,max_length=16,unique=True)
# 告诉ORM 这张表和book表是多对多的关系,ORM自动生成第三章表
book = models.ManyToManyField(to="Book")
def __str__(self):
return "<Author Object: {}>".format(self.name)
class Person(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField(default=18)
birthday = models.DateField(auto_now_add=True)
class Assets(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=64,unique=True,null=False)
number = models.IntegerField(unique=True,null=False)
network_ip = models.GenericIPAddressField(unique=True,null=False)
add_time = models.DateField(auto_now_add=True)
update_time = models.DateField(auto_now=True)
def __str__(self):
return "{}{}{}{}".format(self.id,self.name,self.network_ip,self.add_time)