create database test1;
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': 'localhost',
'PORT': '3306',
'USER': 'root',
'PASSWORD': '12345',
'NAME': 'test1',
}
}
在app的models中
from django.db import models
class Stu(models.Model):
class Meta():
db_table = 't_stu' # 表名
id = models.AutoField(primary_key=True) # id int primary key auto_increment
username = models.CharField(max_length=30) # username varchar(30)
关键字 | 说明 |
---|---|
AutoField | 自动增长的整数(相当于:int auto_increment) 说明: 常用的参数:primary_key=True(定义主键) 如果不写id=models.AutoField(primary_key=True),django也会创建一个自增的主键id |
IntegerField | 整数 int |
FloatField | 浮点数 必填参数: max_digits:最大总位数 decimal_places:小数位数 |
Decimal | 定点数 必填参数: max_digits:最大总位数 decimal_places:小数位数 |
CharField | 字符串 varchar() 必填参数: max_length:最大长度 |
TextField | 大文本 Text |
BooleanField | True|False |
NullBooleanField | null|True或|False |
DateField | 日期 Date: YYYY-MM-DD(常用参数): auto_now:每次修改对象,自动设置时间 auto_now_add:第一次被创建,自动设置时间 |
DateTimeField | 日期 Datetime: YYYY-MM-DD HH:MM:SS(常用参数): auto_now:每次修改对象,自动设置时间 auto_now_add:第一次被创建,自动设置时间 |
TimeField | 时间:Time:HH:MM:SS |
EmailFiled | 邮箱 |
ImageField | 图片 |
例如:
from django.db import models
class Student(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=16)
关键字 | 说明 | 默认值 | 是否要迁移修改表结构 |
---|---|---|---|
primary_key | 是否是主键 | False | 是 |
null | 能否为空 | False | 是 |
unique | 能否重复 | False | 是 |
default | 默认值 | 是 | |
blank | 在django管理后台新增或编辑一条表数据时,该字段能否为空 null是数据库范畴,blank是表单验证范畴 |
False | 否 |
db_column | 表字段名称 | 属性名称 | 是 |
choices | 在django管理后台新增或编辑一条表数据时,显示为下拉框 | 否 |
from django.db import models
class Student(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=16,unique=True)
from django.db import models
from hashlib import md5
import datetime
# 用户模型类
class User(models.Model):
account = models.CharField(max_length=16,unique=True) # 登录账号
username = models.CharField(max_length=16,null=True,db_index=True) # 用户昵称
_password = models.CharField(max_length=32) # 密码,使用md5加密
gender = models.IntegerField(default=0) # 性别,0:男,1:女
birthday = models.DateField(null=True) # 生日
money = models.DecimalField(max_digits=10,decimal_places=2,default=0) # 余额,总位数10,小数位2,默认0
email = models.EmailField(null=True) # 邮箱
image = models.ImageField(null=True) # 头像
createDatetime = models.DateTimeField(auto_now_add=datetime.datetime.now()) # 创建时间
updateDatetime = models.DateTimeField(auto_now=datetime.datetime.now()) # 最近一次修改时间
isdelete = models.BooleanField(default=False) # 逻辑删除
@property
def password(self):
return self._password
@password.setter
def password(self,password):
self._password = md5(password.encode('ascii')).hexdigest()、
def __str__(self):
return 'User对象—> id=%s,username=%s' % (self.id,self.username)
# 创建user表数据
def build_user(num = 100):
for i in range(num):
User.objects.create(
account = '%05d' % i,
username = 'name%s' % i,
password = str(i),
gender = i % 2,
birthday = datetime.datetime.now() + datetime.timedelta(days=i),
money = i ** 2 + 12.34 * i + 100,
email = '%[email protected]' % i,
createDatetime=datetime.datetime.now(),
updateDatetime=datetime.datetime.now(),
isdelete=i % 2,
)
python manage.py makemigrations
python manage.py migrate
python manage.py shell
>> from 【app名字】.models import *
>> build_user()
查询格式:
方法 | 说明 |
---|---|
get(字段名=值) | 返回一个满足条件的对象,如果有多个对象满足条件,报异常 |
all() | 返回所有数据 |
filter(条件) | 返回条件的数据 |
exclude(条件) | 返回不满足条件的数据 |
返回结果:
QuerySet的特点:
QuerySet的对象方法:
方法 | 说明 |
---|---|
count() | 返回结果的总条数 |
first() | 返回第一个对象 |
last() | 返回最后一个对象 |
exists() | 判断查询集中是否有数据,返回True|False |
order_by(【字段1】,-【字段】) | 先根据【字段1】升序排列,然后根据【字段2】降序排列 |
[start,end] | 分页 |
注意:
user1 = User.objects.get(id=1)
print(user1)
try:
User.objects.get(id=10000) # 没有id=10000的对象
except:print('没有满足条件的对象,抛出异常')
try:
User.objects.get(isdelete=0) # 多个对象满足条件
except:print('多个对象满足条件,抛出异常')
'''【结果】
>> User对象—> id=1,username=name0
>> 没有满足条件的对象,抛出异常
>> 多个对象满足条件,抛出异常
'''
user_s = User.objects.all()
print('user_s的类型是:',type(user_s))
for user in user_s:
print(user)
'''【结果】
>> user_s的类型是:
>> User对象—> id=1,username=name0
>> User对象—> id=2,username=name1
>> User对象—> id=3,username=name2
>> ... ...
>> ... ...
'''
user_s = User.objects.filter(id=1)
print('user_s的类型是:',type(user_s))
print(user_s)
'''【结果】
>> user_s的类型是:
>> id=1,username=name0>]>
'''
# 查询id不为1的user对象
user_s = User.objects.exclude(id=1)
user_s = User.objects.exclude(id=1)
ret_exists = user_s.exists() # 结果集是否有数据
ret_count = user_s.count() # 结果集中数据个数
ret_first = user_s.first() # 结果集中第一个数据
ret_last = user_s.last() # 结果集中最后一个数据
ret_1_10 = user_s[1:10] # 结果集切片,不支持负索引
print('ret_exists=',ret_exists)
print('ret_count=',ret_count)
print('ret_first=',ret_first)
print('ret_last=',ret_last)
print('ret_1_10=',ret_1_10)
'''【结果】
>> ret_exists= True
>> ret_count= 99
>> ret_first= User对象—> id=2,username=name1
>> ret_last= User对象—> id=100,username=name99
>> ret_1_10= id=3,username=name2>,... ... id=11,username=name10>]>
'''
【模型类中的字段名】__【条件关键字】=【比较值】
比较条件 | 关键字 |
---|---|
判断相等 | exact |
模糊查询 | 包含:contains 开头:startswidth 结尾:endswith |
是否为空 | isnull |
范围查询 | in |
比较运算 | 大于:gt 大于等于:gte 小于:lt 小于等于:lte |
日期查询 | 年:year 月:month 日:day 小时:hour 分钟:minute 秒:second |
# 没有被逻辑删除的User
user1_s = User.objects.filter(isdelete=0)
print(user1_s)
user2_s = User.objects.filter(isdelete__exact=0)
print(user2_s)
'''【结果】
>> id=1,username=name0>, id=3,username=name2>, ... ...
>> id=1,username=name0>, id=3,username=name2>, ... ...
'''
# 查询用户名中包含'1'的用户
user1_s = User.objects.filter(username__contains='1')
print(user1_s)
# 查询用户名已以'name1'开头的用户
user2_s = User.objects.filter(username__startswith='name1')
print(user2_s)
# 查询邮箱以'@qq.com'结尾的用户
user3_s = User.objects.filter(email__endswith='@qq.com')
print(user2_s)
# 查询生日为空的User对象
user_s = User.objects.filter(birthday__isnull=True)
print(user_s)
# 查询username属于['name1','name2']的User对象
user_s = User.objects.filter(username__in=['name1','name2'])
print(user_s)
# 查询余额大于等于1000的User对象
user_s = User.objects.filter(money__gte=1000)
print(user_s)
# 查询生日中的'日'大于20号的User用户
user_s = User.objects.filter(birthday__day='20')
print(user_s)
from django.db.models import F
# 查询在第一次创建后,发生修改的对象
user_s = User.objects.filter(updateDatetime__gt=F('createDatetime'))
print(user_s)
from django.db.models import Q
# 查询余额大于5000块的男性
print(User.objects.filter(money__gt=5000,gender=0)) # 第一种 逗号
print(User.objects.filter(Q(money__gt=5000) & Q(gender=0))) # 第二种 Q(【条件】)&Q(【条件】)
# 查询余额大于5000块的男性和余额大于2000的女性
print(User.objects.filter(Q(money__gt=5000,gender=0)|Q(money__gt=2000,gender=1)))
# 得到上个查询结果的补集
print(User.objects.filter(~Q(money__gt=5000,gender=0)&~Q(money__gt=2000,gender=1)))
方法 | 说明 |
---|---|
order_by(【字段1】,-【字段】) | 先根据【字段1】升序排列,然后根据【字段2】降序排列 |
# 先根据createDatetime升序排列,对于createDatetime相同的数据,安装birthday降序排列
user_s = User.objects.all().order_by('createDatetime','-birthday')
print(user_s)
关键字 | 说明 |
---|---|
Sum | 求和 |
Max | 最大值 |
Min | 最小值 |
Avg | 平均值 |
Count | 个数 |
from django.db.models import Avg
# 查询所有用户的余额平均值
money_all_avg = User.objects.aggregate(Avg('money'))
print(money_all_avg)
# 查询所有男用户的余额平均值
money_men_avg = User.objects.filter(gender=0).aggregate(Avg('money'))
print(money_men_avg)
'''【结果】
>> {'money__avg': 3994.33}
>> {'money__avg': 3938.66}
'''
# 创建新的User
user = User(account='00101',username='name101',password='101')
user.save()
# 在save后 user会更新为数据库中存在的数据
print(user.id)
# 修改user
user.password = '102'
user.save() # 把name101的密码改为102
说明:
格式:【模型类名】.objects.create(字段名=字段值,… …)
user = User.objects.create(account='00102',username='name102',password='102')
print(user)
'''【结果】
>> User对象—> id=102,username=name102
'''
# 修改余额大于等于8000的用户的isdelete = 1,返回值是修改的行数
ret = User.objects.filter(money__gt=8000).update(isdelete=1)
print(ret)
'''【结果】
>> 17
'''
# 物理删除
User.objects.filter(money__gt=10000).delete()
关键字 | 说明 |
---|---|
ForeignKey | 一对多 定义在多的一端中 |
ManyToManyField | 多对多 定义在任意一方 |
OneToOneField | 一对一 定义在任意一方 |
关键字 | 说明 |
---|---|
to | 引用的模型类 |
on_delete | 外键约束 on_delete=models.CASCADE 级联操作(多对一,一的一方删除,多的一方也删除) on_delete=models.PROTECT 报异常(被引用的一方不能删除) on_delete=models.SET_NULL 设置为null(多对一,一的一方删除,多的一方外键为null) on_delete=models.DO_NOTHING 什么也不做 |
related_name | 反向引用,如果两个表间有多种外键关系,需要指明related_name |
models类:
from django.db import models
class User1(models.Model):
name = models.CharField(max_length=16,unique=True) # 用户名
class Forum1(models.Model):
name = models.CharField(max_length=16,unique=True) # 帖子主题
# 发帖的用户
userObject = models.ForeignKey( to=User1, # ‘一’的一方的类
on_delete=models.CASCADE # 级联操作
)
一对多的数据维护与查询
# 添加用户
user = User1.objects.create(name='name1')
# 添加帖子,引用上面创建的用户
Forum1.objects.create(name='topic1',userObject=user)
# 得到用户发的所有帖子
# 一对多,【多的一方的class名小写_set】
forum_s = User1.objects.get(id=1).forum1_set.all()
print(forum_s)
# 得到帖子发送者对象
# 多对一,【通过定义的外键字段引用】
user = Forum1.objects.get(name='topic1').userObject
print(user)
'''【结果】
> ]>
> User1 object
'''
1:M —>表示1对多
M得到引用的1:通过M中定义的外键字段,得到1
1得到被应用的所有M:通过M方的类名_set,返回时QuerySet对象,例如user1.forum1_set.all()
django会自动创建一个中间表:名称:【app名】【类名小写】【类名小写】
添加引用关系方法:add()
删除引用关系方法:remove()
class User2(models.Model):
name = models.CharField(max_length=16,unique=True) # 用户名
def __str__(self):
return str(self.name)
class Hobby2(models.Model):
name = models.CharField(max_length=16,unique=True) # 爱好名称
userobjects = models.ManyToManyField(to=User2) # 多对多
def __str__(self):
return str(self.name)
user1 = User2.objects.create(name='name1')
user2 = User2.objects.create(name='name2')
# 创建3个爱好对象
hobby1 = Hobby2.objects.create(name='早上写代码')
hobby2 = Hobby2.objects.create(name='中午写代码')
hobby3 = Hobby2.objects.create(name='晚上写代码')
# 通过用户,添加引用
user1.hobby2_set.add(hobby1)
user1.hobby2_set.add(hobby2)
# 通过爱好,添加引用
hobby3.userobjects.add(user1)
hobby3.userobjects.add(user2)
print(user1.hobby2_set.all())
print(hobby3.userobjects.all())
# hobby3删除引用的user1
hobby3.userobjects.remove(user1)
print(hobby3.userobjects.all())
'''【结果】
>> , , ]>
>> , ]>
>> ]>
'''
through指明中间表的模型类,如果自己指明了中间表,那么django就不会帮助维护了,所有的添加删除引用关系,都必须自己手动完成。
class User3(models.Model):
name = models.CharField(max_length=16, unique=True) # 用户名
def __str__(self):
return str(self.name)
class Hobby3(models.Model):
name = models.CharField(max_length=16, unique=True) # 爱好名称
userobjects = models.ManyToManyField(to=User3,through='User3ToHobby3') # 多对多
def __str__(self):
return str(self.name)
class User3ToHobby3(models.Model):
user = models.ForeignKey(to=User3)
hobby = models.ForeignKey(to=Hobby3)
# 创建用户对象
user1 = User3.objects.create(name='name1')
user2 = User3.objects.create(name='name2')
# 创建爱好对象
hobby1 = Hobby3.objects.create(name='早上写代码')
hobby2 = Hobby3.objects.create(name='中午写代码')
hobby3 = Hobby3.objects.create(name='晚上写代码')
# 自己手动维护中间表
User3ToHobby3.objects.create(user=user1,hobby=hobby1)
User3ToHobby3.objects.create(user=user1,hobby=hobby2)
User3ToHobby3.objects.create(user=user2,hobby=hobby2)
User3ToHobby3.objects.create(user=user2,hobby=hobby3)
print(user1.hobby3_set.all())
print(hobby3.userobjects.all())
'''【结果】
>> , ]>
>> ]>
'''
to = ‘self’ 实现自关联
注意:
class Area(models.Model):
name = models.CharField(max_length=16,unique=True) # 地区名字
pArea = models.ForeignKey(to='self',null=True) # 上一级地区的引用
def __str__(self):
return str(self.name)
# area1:北京
area1 = Area.objects.create(name='北京')
# area2:朝阳
area2 = Area(name='朝阳')
# 设置area2的父地区是area1北京
area2.pArea = area1
area2.save()
# area3:丰台
area3 = Area.objects.create(name='丰台')
# area1北京的子地区,添加area3丰台
area1.area_set.add(area3)
area_beijing = Area.objects.get(name='北京')
area_chaoyang = Area.objects.get(name='朝阳')
area_fengtai = Area.objects.get(name='丰台')
# 打印北京的所有子区域
print(area_beijing.area_set.all())
# 打印朝阳的父区域
print(area_chaoyang.pArea)
'''【结果】
>> , ]>
>> 北京
'''
from django.db import models
from hashlib import md5
import datetime
class User(models.Model):
account = models.CharField(max_length=16,unique=True) # 登录账号
username = models.CharField(max_length=16,null=True,db_index=True) # 用户昵称
_password = models.CharField(max_length=32) # 密码,使用md5加密
gender = models.IntegerField(default=0) # 性别,0:男,1:女
birthday = models.DateField(null=True) # 生日
money = models.DecimalField(max_digits=10,decimal_places=2,default=0) # 余额,总位数10,小数位2,默认0
email = models.EmailField(null=True) # 邮箱
image = models.ImageField(null=True) # 头像
createDatetime = models.DateTimeField(auto_now_add=datetime.datetime.now()) # 创建时间
updateDatetime = models.DateTimeField(auto_now=datetime.datetime.now()) # 最近一次修改时间
isdelete = models.BooleanField(default=False) # 逻辑删除
@property
def password(self):
return self._password
@password.setter
def password(self,password):
self._password = md5(password.encode('ascii')).hexdigest()
def __str__(self):
return str(self.username)
class Forum(models.Model):
topic = models.CharField(max_length=100,unique=True)
createDatetime = models.DateTimeField(auto_now_add=datetime.datetime.now()) # 创建时间
updateDatetime = models.DateTimeField(auto_now=datetime.datetime.now()) # 最近一次修改时间
sender = models.ForeignKey(to=User,on_delete=models.DO_NOTHING,related_name='sender_set')
collectors = models.ManyToManyField(to=User,related_name='collectors_set')
isdelete = models.BooleanField(default=False) # 逻辑删除
def __str__(self):
return str(self.topic)
def build_user(num = 100):
for i in range(num):
User.objects.create(
account = '%05d' % i,
username = 'name%s' % i,
password = str(i),
gender = i % 2,
birthday = datetime.datetime.now() + datetime.timedelta(days=i),
money = i ** 2 + 12.34 * i + 100,
email = '%[email protected]' % i,
createDatetime=datetime.datetime.now(),
updateDatetime=datetime.datetime.now(),
isdelete=i % 2,
)
# ---------------这里重置一下数据库,重新执行一下build_user()----------------
# 根据id得到3个user对象
user1 = User.objects.get(id=1)
user2 = User.objects.get(id=2)
user3 = User.objects.get(id=3)
# 创建两个帖子forum对象
forum1 = Forum(topic='话题1')
forum2 = Forum(topic='话题2')
# forum1和forum2的发帖人都是user1
forum1.sender = user1
forum2.sender = user1
# 保存forum
forum1.save()
forum2.save()
# 用户2收藏帖子1
user2.collectors_set.add(forum1)
user2.save()
# 帖子1被用户3收藏
forum1.collectors.add(user3)
forum1.save()
print('查询id为1的用户发送的所有帖子', User.objects.get(id=1).sender_set.all())
print('查询id为1的帖子的所有收藏者',Forum.objects.get(id=1).collectors.all())
print('查询帖子,且发帖者的创建时间在2019-05-10之后', Forum.objects.filter(sender__createDatetime__gt='2019-05-10'))
print('查询用户,且用户的关注的帖子的topic中包含"1"', User.objects.filter(collectors_set__topic__contains='1'))
'''【结果】
>> 查询id为1的用户发送的所有帖子 , ]>
>> 查询id为1的帖子的所有收藏者 , ]>
>> 查询帖子,且发帖者的创建时间在2019-05-10之后 , ]>
>> 查询用户,且用户的关注的帖子的topic中包含"1" , ]>
'''
# 定义一个Manager类,需要继承models.Manager
class MyManager(models.Manager):
# 自定义一个方法,得到所有没有逻辑删除的数据
def all_isnotdetele(self):
# 调用父类方法,传递参数
return super().filter(isdelete=False)
class User4(models.Model):
# 在模型类中实例化自己的管理器
manager = MyManager()
# 定义字段
username = models.CharField(max_length=30)
isdelete = models.BooleanField(default=False)
User4.manager.create(username='name1')
User4.manager.create(username='name2',isdelete=True)
print(User4.manager.all())
print(User4.manager.all_isnotdetele())
'''【结果】
>> , ]>
>> ]>
'''
objects其实是模型类的默认管理器
一个模型类中只能有一个管理器,如上,如果实例化manager = MyManager(),那么就不能使用User4.objects了,只能使用User4.manager。
也可以重写管理器的方法,例如:
class MyManager(models.Manager):
# 重写管理的方法
def all(self):
return super().filter(isdelete=False)