Django中的ORM模型
项目配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', #数据库引擎
'NAME': 'django_data', #数据库名
'USER': 'mj', #账户名
'PASSWORD': 'x', #密码
'HOST': 'x', #主机
'PORT': '3306', #端口
}
}
-
配置选项
-
default-默认的数据库,可配置多个
-
ENGINE-模板引擎
-
-
sqlite3的配置选项
-
只需要指定数据库引擎和数据库文件名称即可
-
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', #数据库引擎
'NAME': 'mydatabase.db', #数据库名
}
}
-
安装依赖
pip install mysqlclient
常见的ORM字段类型
Django ORM类型映射
Django中的模型代码
文本
-
CharField、TextField-字符串、文本
-
FileField、lmageField--文件、图片
-
FilePathField--文件路径
-
EmailField--邮件地址
-
URLField--URL地址
整数
-
IntegerField--整数
-
SmalllntegerField--整数
-
BiglntegerField-整数
-
BooleanField-布尔值(1,0)
-
PositivelntegerField-正整数
小数
-
FloatField、DecimalField一-小数
时间
-
DateField一日期
-
TimeField-时间
特殊关系
-
OneToOneField--一对一关联
-
ForeignKey--外键关联
-
ManyToManyField--多对多关联
-
GenericForeignKey--复合关联
类型的选项
-
每个类型都有可选参数,部分类型有必传参数
-
参数传递是无序的(需要写参数的名称)
-
一般情况下,第一个参数不指定名称
常用
-
CharField
-
max_length--最大长度
-
相关类型
-
EmailField
-
URLField
-
-
-
DateTimeField
-
auto_now--更新时间记录更改时的时间
-
auto_now_add--记录创建的时间(注册时使用)
-
模型的创建
from django.db import models
class User(models.Model):
"""用户模型"""
name = models.CharField('姓名', max_length=64)
sex = models.CharField('性别', max_length=1, choices=(
('1', '男'),
('0', '女')
),default='1')
#年龄正整数
age = models.PositiveIntegerField('年龄',default=0)
#用户名不能重复unique
username = models.CharField('用户名',max_length=64,unique=True)
password = models.CharField('密码',max_length=256)
remark = models.CharField('备注',max_length=64,null=True,blank=True)
created_at = models.DateTimeField('注册时间',auto_now_add=True)
updated_at = models.DateTimeField('最后修改时间',auto_now=True)
模型同步migrate
实现模型同步
-
检查settings.py
-
注册app
-
检查数据库
-
检查模型:
python manage,py check -
使用migrate执行同步:
-
python manage.py makemigrations -
python manage.py migrate
-
模型的元数据
元数据的描述
使用Meta类来表示
-
对模型的补充说明
-
示例
class Meta:
verbose_name = '用户基础信息'
verbose_name_plural = '用户基础信息'
db_table = 'oauth_user' #指定模型表名称
-
db_table--模型映射的数据库表的名称
-
ordering--指定数据表的默认排序规则
-
verbose_name--供编程查看的字段名称(便于阅读)
abstract--抽象类
-
抽象类不会生成数据库表
-
class CommonModel(models.Model):
"""自定义模型的基类 这个类不会生成具体的数据表"""
created_at = models.DateTimeField('注册时间', auto_now_add=True)
updated_at = models.DateTimeField('最后修改时间', auto_now=True)
class Meta:
abstract = True -
抽象类可被继承
class Profile(CommonModel):
nickname = models.CharField('昵称', max_length=64)
-
生成的Profile表中有
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"created_at",
models.DateTimeField(auto_now_add=True, verbose_name="注册时间"),
),
(
"updated_at",
models.DateTimeField(auto_now=True, verbose_name="最后修改时间"),
),
("nickname", models.CharField(max_length=64, verbose_name="昵称")),
],
proxy--代理模型(对父模型功能的扩充)
-
比如User是一个基类,现在有一个角色是管理员,管理员可以代理User的所有属性并进行扩充,这样不会让User过于冗杂
-
class Manager(User):
class Meta:
proxy = True
外键关联类型
关联关系
-
一对一
-
一对多
-
多对多
一对一关系
-
OneToOneField(to,on_delete,parent_link=False,**options)
-
举例:用户信息进行分表
-
用户基本信息<--用户详细信息
-
一对多关系
-
Foreignkey(to,on_delete,**options)
-
举例:用户提问
-
一个用户可以提问多个问题
-
此时在问题这个表上加上一个Foreignkey指向用户表,这样就可以使用一对多
-
class Profile(CommonModel):
"""用户相信信息"""
"""拿到一个用户的基础信息,通过张三来取到详细信息
在此建立一个反向引用
"""
# zhangsan = User()
# zhangsan.profile
user = models.OneToOneField('User', on_delete=models.CASCADE,
related_name='profile',
db_column='user')
"""OnetoOne在数据库表中都会默认加上一个id user_id
db.colum把名字改为user
"""
nickname = models.CharField('昵称', max_length=64)
class Question(CommonModel):
"""问题"""
name = models.CharField('问题名称', max_length=64)
class Answer(CommonModel):
question = models.ForeignKey(Question, on_delete=models.CASCADE,
related_name='answers',
verbose_name='关联的问题')
content = models.TextField('答案的问题')
class Classify(models.Model):
"""分类
1 酒水 假设在数据库中拿到酒水,那么通过children可以拿到下面两个记录
2 啤酒 假设在数据库中拿到啤酒,那么通过parent可以拿到酒水这个对象
3 白酒
"""
name = models.CharField('名称', max_length=64)
parent = models.ForeignKey('self', related_name='children',
on_delete=models.CASCADE)
多对多
-
ManyToManyField(to,**options)
-
举例:收藏问题
-
用户可以收藏多个问题,一个问题可以被多个用户收藏
-
class User(models.Model):
......
collect_ques = models.ManyToManyField('Question')
类型的参数选项
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
class CommonModel(models.Model):
"""自定义模型的基类 这个类不会生成具体的数据表"""
created_at = models.DateTimeField('注册时间', auto_now_add=True)
updated_at = models.DateTimeField('最后修改时间', auto_now=True)
class Meta:
abstract = True
class User(models.Model):
"""用户模型"""
name = models.CharField('姓名', max_length=64)
sex = models.CharField('性别', max_length=1, choices=(
('1', '男'),
('0', '女')
), default='1')
# 年龄正整数
age = models.PositiveIntegerField('年龄', default=0)
# 用户名不能重复unique
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)
collect_ques = models.ManyToManyField('Question')
class Meta:
db_table = 'user'
class Manager(User):
class Meta:
proxy = True
class Profile(CommonModel):
"""用户相信信息"""
"""拿到一个用户的基础信息,通过张三来取到详细信息
在此建立一个反向引用
"""
# zhangsan = User()
# zhangsan.profile
user = models.OneToOneField('User', on_delete=models.CASCADE,
related_name='profile',
db_column='user')
"""OnetoOne在数据库表中都会默认加上一个id user_id
db.colum把名字改为user
"""
nickname = models.CharField('昵称', max_length=64)
class Question(CommonModel):
"""问题"""
