文章目录
ORM的好处:
- 面向对象的编程思想,方便扩充
- 少写SQL,提高开发效率
- 支持多种类型的数据库,方便切换
- 技术成熟,能解决大部分问题
Django ORM支持的数据库:MySQL,SQLite,ORACLE,MariaDB,PostgreSQL
与Flask的区别: - Django自带ORM
- Flask需要使用扩展
Django ORM 配置
项目配置(settings.py)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydatabase',
'USER': 'root',
'PASSWORD': '12345678',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
default——默认的数据库,可配置多个数据,使用名称来区分
ENGINE——数据库引擎
- ‘django.db.backends.postgresql’
- ‘django.db.backends.mysql’
- ‘django.db.backends.sqlite3’
- ‘django.db.backends.oracle’
配置选项: - NAME——数据库名称
- USER——数据库登录用户名
- PASSWORD——数据库登录密码
- HOST——数据库访问地址
- PORT——数据库访问端口
常见的ORM字段类型
文本
- CharField、TextField——字符串、文本
- FileField、ImageField——文件、图片
- FilePathField——文件路径
- EmailField——邮件地址
- EmailField——邮件地址
数字(整数)
- IntegerField——整数
- SmallIntegerField——整数
- BigIntegerField——整数
- BooleanField——布尔值(1,0)
- PositiveIntegerField——正整数
数字(小数)
- FloatField、DecimalField——小数
日期与时间
- DateField——日期
- TimeField——时间
- DateTimeField——日期时间
特殊类型
- OneToOneField——一对一关联
- ForeignKey——外键关联
- ManyToManyField——多对多关联
- GenericForeignKey——复合关联
模型基类
django.db.models.Field
类型之间的关系:
类型的选项(可选参数)
每个类型都有可选参数,部分类型有必传参数
参数传递是无序的(需要写参数的名称)
参数传递是无序的(需要写参数的名称)
-
verbose_name:大多数模型类型的第一个参数,该字段的含义
特例:ForeignKey、ManyToManyField 、OneToOneField -
null、blank——是否为Null、空值
-
db_column——数据库表中对应的字段名称
-
default——不填写改字段值时的默认值
-
primary_key、unique——主键、唯一索引
-
help_text——帮助文字
-
choices——可供选择的选项,如:性别的选项(男,女)
-
get_FOO_display()——展示choices对应的值
class User(models.Model):
""" 用户模型 """
name = models.CharField('姓名', db_column='username',max_length=64)
age = models.PositiveIntegerField('年龄', default=0)
CharField
max_length——最大长度
相关类型:EmailField——邮件输入,URLField——URL输入
DateTimeField
auto_now——更新时间为记录更改时的时间
auto_now_add——记录创建的时间
模型的创建
把用户当作一个对象分析,看有哪些属性即字段,并将类型设计出来。
示例:
from django.db import models
# Create your models here.
class User(models.Model):
name = models.CharFiled('姓名', max_length=64)
sex = models.CharFiled('性别', max_length=1, choices=(
('1', '帅哥'),
('2', '美女'),
), default='1')
age = models.PositiveIntegerField('年龄', default=0)
username = models.CharField('用户名', max_length=64, unique=True)
password = models.CharField('密码',max_length=256)
remark = models.CharField('备注', max_length=64,null=True, blank=True)
create_time = models.DateTimeField('注册时间', auto_now_add=True)
update_time = models.DateTimeField('修改时间', auto_now=True)
模型同步
前提:确认settings.py已将模型添加到INSTALLED_APPS
步骤一:检查模型是否编写正确
python manage.py check
步骤二:使用makemigrations生成同步原语
python manage.py makemigrations
步骤三:使用migrate执行同步
python manage.py migrate
模型变更(添加、修改、删除)了一些字段,怎么快速的修改数据库对应的表结构?
重复上述操作即可。
模型的元数据
一、元数据的描述
使用Meta类来表示,对模型的补充说明
class Meta:
verbose_name =' '
verbose_name_plural =' '
db_table = 'oauth_user'
- db_table——模型映射的数据库表的名称
- ordering——指定数据表的默认排序规则
- verbose_name——供编程查看的字段名称(便于阅读)
- abstract——抽象类,抽象类不会生成数据库表
- proxy——代理模型,对父模型的功能进行扩充
抽象类的使用:
很多模型中都会用到create_time和update_time,那么就不需要每个模型都写一遍,可以定义一个公共的模型类。
class CommonModule(models.Model):
# 自定义模型的基类
create_time = models.DateTimeField('注册时间', auto_now_add=True)
update_time = models.DateTimeField('修改时间', auto_now=True)
class Meta:
# 抽象类,不会生成对应的数据表
abstract = True
User类继承CommonModule。
class User(CommonModule):
name = models.CharFiled('姓名', max_length=64)
sex = models.CharFiled('性别', max_length=1, choices=(
('1', '帅哥'),
('2', '美女'),
), default='1')
age = models.PositiveIntegerField('年龄', default=0)
username = models.CharField('用户名', max_length=64, unique=True)
password = models.CharField('密码',max_length=256)
remark = models.CharField('备注', max_length=64,null=True, blank=True)
email = models.EmailField('用户的邮箱', max_length=64, null=True, blank=True)
class Meta:
db_table = 'user'
proxy代理模型的使用:
用户模型User分为两类,一类是管理员,一类是游客。
class Manager(User):
class Meta:
proxy = True
def xxx(self):
# 对功能的增加
pass
数据库中常见的关联关系
一对一、一对多、多对多
一对一关系
OneToOneField(to, on_delete, parent_link=False,**options)
举例:用户信息进行分表
class Profile(CommonModule):
# 用户详细信息
# zhangsan = User()
# zhangsan.profile
user = models.OneToOneField('User', on_delete=models.CASCADE,
related_name='profile')
nickname = models.CharField('昵称', max_length=64)
一对多关系
ForeignKey(to, on_delete,**options)
举例:用户提问
class Question(CommonModule):
name = models.CharField('问题名称', max_length=64)
class Answer(CommonModule):
question = models.ForeignKey(Question, on_delete=models.CASCADE,
related_name='answers',
verbose_name='关联的问题')
name = models.TextField('问题答案')
class Classify(models.Model):
# 分类
# 1 酒水
# 2 啤酒
# 3 白酒
name = models.CharField('名称', max_length=64)
parent = models.ForeignKey('self', related_name='children',
on_delete=models.CASCADE)
多对多关系
ManyToManyField(to,**options)
举例:收藏问题
collect_ques = models.ManyToManyField('Qusetion')
类型的参数选项
- to——关联的模型(必传)
模型类,模型类(字符串),self - on_delete——删除选项(必传)
CASCADE:关联删除
PROTECT:受保护,不允许被删除
SET_NULL:设置为None,需要添加选项null=True
SET_DEFAULT:设置为默认值,需要添加选项default
SET() :传参设置值
DO_NOTHING :什么也不做 - related_name 是否需要反向引用,反向引用的名称
- related_query_name 反向引用的名称
复合类型
举例:评论景点、评论订单
上面需要几张数据库表?
from django.db import models
# Create your models here.
class Sight(models.Model):
name = models.CharField('景点名称', max_length=64)
address = models.CharField('景点地址', max_length=64)
class Order(models.Model):
sn = models.CharField('订单号', max_length=64)
amount = models.FloatField('订单金额')
class SightComment(models.Model):
# 景点评论
content = models.CharField('评论内容', max_length=512)
score = models.FloatField('分数', default=5)
class OrderComment(models.Model):
# 订单评论
content = models.CharField('评论内容', max_length=512)
score = models.FloatField('分数', default=5)
景点评论和订单评论的结构是相同的,进行优化。
优化后的解决方案:
- ContentType——类容模型
- ForeignKey(ContentType)——关联复合模型
- GenericForeignKey——关联模型
- GenericRelation——反向关联
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
# Create your models here.
class Sight(models.Model):
name = models.CharField('景点名称', max_length=64)
address = models.CharField('景点地址', max_length=64)
class Order(models.Model):
sn = models.CharField('订单号', max_length=64)
amount = models.FloatField('订单金额')
comments = GenericRelation('Comment', related_name='order_comments')
# class SightComment(models.Model):
# # 景点评论
# content = models.CharField('评论内容', max_length=512)
# score = models.FloatField('分数', default=5)
#
#
# class OrderComment(models.Model):
# # 订单评论
# content = models.CharField('评论内容', max_length=512)
# score = models.FloatField('分数', default=5)
class Comment(models.Model):
# 评论
# comment = Comment()
# comment.order
# comment.sight
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
# 判断是order还是sight
content_object = GenericForeignKey('content_type', 'object_id')
content = models.CharField('评论内容', max_length=512)
score = models.FloatField('分数', default=5)