一、创建子应用
进入manage.py同级目录
执行命令
python manage.py startapp appname
在setting中注册子应用
二、Django ORM
创建模型
from django.db import models
class StoreUser(models.Model):
# 属性
# id 不需要编写,Django的ORM自动生成id
# id = models.IntegerField(primary_key=True,auto_created=True)
username = models.CharField(max_length=32,verbose_name="用户名")
password = models.CharField(max_length=32,verbose_name="密码")
nick_name = models.CharField(max_length=32,verbose_name="昵称")
age = models.IntegerField(verbose_name="年龄")
gender = models.IntegerField(verbose_name="性别(1-男,0-女)")
email = models.EmailField(verbose_name="邮箱")
address = models.TextField(verbose_name="地址")
create_time = models.DateField(verbose_name="创建时间")
(一)字段类型
字段类型 | 描述 |
---|---|
IntegerField | 整形 |
CharField | 字符串类型,同步成表中的varchar类型,创建的时候需要指定长度(max_length) |
EmailField | 邮箱类型 |
TextField | 长文本类型 |
DatetimeField | 日期类型 |
DateField | 日期类型 |
ImageField | 图片类型,需要配合pillow使用,并且需要在settings增加媒体文件的配置,同时接受upload_to的字段类型。该字段能够完成图片上传。 |
FloatField | 浮点型 |
(二)字段类型
字段属性 | 说明 |
---|---|
primary_key | 主键 |
auto_created | 自增 |
verbose_name | 当做一个注释使用,在站点管理中为字段起名字 |
max_length | 常用来为字符串指定长度 |
upload_to | 配合imgfield字段使用,用来指定图片上传的路径 |
auto_now | 在日期字典类型中使用,用来使用当前时间 |
default | 默认值 |
choices | 列举可选址,选择。在站点管理中会议下拉框显示 |
null | 可空,数据库表可空 |
blank |
(三)链接sqlite
在setting中添加配置
(四)链接mysql
1、创建库
create database name charset=utf8;
2在setting中配置mysql
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "demo", # 使用的库名(database)
"USER":"root", # 链接mysql 的用户名
"PASSWORD":"", # 密码
"HOST":"127.0.0.1", # 主机ip
"PORT":"3306" # 端口
}
}
3排错 执行python manage.py check检测错误并排错
- 第一个错误 ,没有mysqldb模块,mysqldb是属于python2的,python3 改为了pymysql
下载并改错
pip install pymysql
第二个错误 python3中字符串没有decode方法
解决,将decode方法改为encode方法
(五)同步表结构
命令
python manage.py check 检测当前环境是否正确
python manage.py makemigrations 将模型的变更生成迁移文件(类似于FLask中的migrate)
python manage.py migrate 执行迁移文件,同步表结构(类使用flask中的upgrade)
上面两个命令,如果直接写,Django项目中的所有app都会生效,可以在命令的后面指定app的名字,指定那个app中的模型生效
默认同步生成的表名为 appname_模型名
修改表名
(六)ORM操作
1.表单操作
增加方法
create
# create 有返回值 返回当前对象
data = StoreUser.objects.create(username="lisi1",password="1111",nick_name="lisi")
print(data)
print(data.username)
save
storeuser = StoreUser()
storeuser.username = "admin"
storeuser.password = "1111"
storeuser.nick_name = "管理员"
storeuser.save()
查询方法
all
查询所有,符合条件的所有数据
返回值为queryset类型
data = StoreUser.objects.all()
print(data)
for one in data:
print(one.username)
choices的使用
get
返回类型对象,结果为有且只有一个,其他情况出异常
data = StoreUser.objects.get(id = 1)
data = StoreUser.objects.get(username="lisi")
data = StoreUser.objects.get(gender=1)
data = StoreUser.objects.get(id=100)
filter 过滤
返回值为 queryset
data = StoreUser.objects.filter(username="admin")
data = StoreUser.objects.filter(username="lisi",gender=1)
first
返回符合条件的第一条数据对象,如果不存在,返回None
data = StoreUser.objects.filter(nick_name="lisi").first()
print(data)
last
data = StoreUser.objects.filter(nick_name="lisi").last()
values
结果为特殊的queryset [{},{},{}]
# values 返回一个特殊的questset
data = StoreUser.objects.values()
print(data)
# 查询admin用户的nickname
data = StoreUser.objects.filter(username="admin").values("nick_name")
print(data)
exists
判断某个数据是否存在,返回结果为布尔
# 判断 是否有 xiaoer
flag = StoreUser.objects.filter(username="xiaoer").exists()
print(flag)
排序
order_by
# order by 按照id 进行排序
# 升序
data = StoreUser.objects.order_by("id").all()
print(data)
# 降序
data = StoreUser.objects.order_by("-id").all()
print(data)
双下滑线查询
# 查询 age > 11 的数据
data = StoreUser.objects.filter(age__gt=11).all()
print(data)
# 模糊查询 like 查询包含“ad” 的所有用户
data = StoreUser.objects.filter(username__contains="ad").all()
print(data)
data = StoreUser.objects.filter(username__startswith="ad").all()
print(data)
# __in 类似于sql中的 in
# 获取id 为 1, 2 5 的数据
data = StoreUser.objects.filter(id__in = [1,2,5]).all()
print(data)
# 获取id 在 1 到 3 内的数据
data = StoreUser.objects.filter(id__range=[1,3]).all()
print(data)
聚合
# 聚合
from django.db.models import Sum,Avg,Count,Min,Max
# 聚合结果为 字典,默认key 为聚合的 字段__聚合方法
# 查询总人数
data = StoreUser.objects.all()
num = len(data)
data = StoreUser.objects.aggregate(Count("id"),Sum("age"))
print(data) # {'id__count': 5,"age__sum":}
# 修改统计之后的 key
data = StoreUser.objects.aggregate(idc = Count("id"), ags = Sum("age"))
print(data) # {'idc': 5, 'ags': 55}
分组
# 分组
# 男 和 女的 人数
# 对象.objects.values("分组条件").annotate(聚合方法)
data = StoreUser.objects.values("gender").annotate(Count("id")) # 结果为queryset
print(data)
F对象
比较同一个模型中的两个字段的大小
from django.db.models import F
# 查询 age > id 的数据
data = StoreUser.objects.filter(age__gt=F("id")+10).all()
Q对象
逻辑关系
and | & |
---|---|
or | | |
not | ~ |
from django.db.models import Q
# and 查询 age 》 10 的 女性
data = StoreUser.objects.filter(age__gt=10,gender=0).all()
data = StoreUser.objects.filter(Q(age__gt=10) & Q(gender=0)).all()
print(data)
# or 查询 age > 10 或者性别为女的
data = StoreUser.objects.filter(Q(age__gt=10) | Q(gender=0)).all()
print(data)
# 查询 非女性
data = StoreUser.objects.filter(~Q(gender=0)).all()
print(data)
分页
data = StoreUser.objects.filter(~Q(gender=0)).all()[1:3]
结果
修改
update 需要在queryset后面使用
StoreUser.objects.filter(id =2).update(age=12)
save
storeuser = StoreUser.objects.get(id = 2)
storeuser.age = 20
storeuser.save()
删除
delete 可以在对象和queryset后面使用
# 对象.delete()
storeuser = StoreUser.objects.get(id =2).delete()
# queryset.delete()
StoreUser.objects.filter(id=4).delete()
StoreUser.objects.all().delete()
2.一对一的操作
参数说明
OneToOneField 设置一对一关系
to 代表和那种模型有关系
to_field 和那种的表的那个字段关联,可以不填,默认为id
on_delete 代表关联表数据删除,对应的数据,应该作何处理
models.PROTECT 如果有外键不允许删除
models.CASCADE 如果删除关联表的数据,对应的数据被删除
如果删除storeuser的数据,store表中对应的数据删除
创建一对一模型
class Store(models.Model):
store_name = models.CharField(max_length=32,verbose_name="店铺名")
store_desc = models.TextField(verbose_name="店铺描述")
store_address = models.TextField(verbose_name="店铺地址")
# 增加 一对一的关系
# OneToOneField 设置一对一关系
# to 代表和那种模型有关系
# to_field 和那种的表的那个字段关联,可以不填,默认为id
# on_delete 代表关联表数据删除,对应的数据,应该作何处理
# models.PROTECT 如果有外键不允许删除
# models.CASCADE 如果删除关联表的数据,对应的数据被删除
# 如果删除storeuser的数据,store表中对应的数据删除
store_user = models.OneToOneField(to=StoreUser,on_delete=models.CASCADE)
增加
storeuser = StoreUser.objects.create(username="admin",password="111",nick_name="管理员")
# 第一种方式
Store.objects.create(
store_name = "店铺01",
store_desc = "店铺01",
store_address = "北京",
store_user_id = storeuser.id
)
# 第二种
Store.objects.create(
store_name = "店铺01",
store_desc = "店铺01",
store_address = "北京",
store_user = storeuser # 对象
)
2查询
从store的对象,查询store_user 的数据
从外键所在的模型,到另一个模型
# 查询 店铺02 的老板
# 第一种
store = Store.objects.filter(store_name="店铺02").first()
store_user_id = store.store_user_id
store_user = StoreUser.objects.get(id = store_user_id)
# 第二种
store = Store.objects.filter(store_name="店铺02").first()
store_user = store.store_user # 对象
print(store_user)
从storeuser 到store的查询
从另一个模型到外键所在的模型
# 查询admin2 用户的店铺
storeuser = StoreUser.objects.filter(username="admin2").first()
# 第一种
# store = Store.objects.filter(store_user_id = store_user.id).first()
# 第二种 一对一的模型中,可以直接使用另一个模型的类名小写
data = storeuser.store
print(data)
删除
根据on_delete 的属性操作
# 删除 CASCADE
# PROTECT
StoreUser.objects.get(id = 6).delete()