Django之Django数据库(三)

一、创建子应用

进入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中添加配置
在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检测错误并排错

  1. 第一个错误 ,没有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()

猜你喜欢

转载自blog.csdn.net/h1751541643/article/details/108780929