erchun

一、使用传统pymysql执行与sqlite区别

①使用pymysql执行原生sql语句来操作数据
1.sql语句比较复杂,且不好管理
2.sql语句安全性无法保持
3.数据库创建、数据表生成、数据添加以及数据迁移等非常麻烦
4.sql语句性能不够好

②使用ORM框架创建数据库
mysql中的对象
1.数据库
需要手动创建数据库

2.数据表
a.与ORM中的模型类一一对应
b.在子应用的models.py中定义模型类

3.字段
a.与模型类的类属性一一对应

4.记录
a.与模型类对象一一对应

 

二、在django中创建数据库

1、settings.py中

# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
# 指定数据库的配置信息
DATABASES = {
    # 使用的默认数据库信息
    \'default\': {
        \'ENGINE\': \'django.db.backends.sqlite3\',
        # a.指定使用的数据库引擎(使用哪种类型数据库?)
        # \'ENGINE\': \'django.db.backends.mysql\',
        # b.指定数据库名称
        \'NAME\': BASE_DIR / \'db.sqlite3\',
        # \'NAME\': \'my_django\',
        # c.指定数据库的用户名
        # \'USER\': \'root\',
        # d.指定数据库的密码
        # \'PASSWORD\': \'123456\',
        # e.指定数据库主机地址
        # \'HOST\': \'localhost\',
        # f.指定数据库的端口号
        # \'PORT\': 3306
    }
}

 

2. models.py中

a.定义模型类必须继承Model或者Model子类,一个模型类相当于一个table
b.定义的类属性(Field对象)为表中的字段信息
c.默认表名为子应用名_模型类名小写
d.默认会自动创建一个id主键(自增、非空)
e.生成迁移脚本:python manage.py makemigrations 子应用名
f.生成的迁移脚本会自动放置到子应用的migrations目录中
g.执行迁移脚本:python manage.py migrate 子应用名

from django.db import models

# Create your models here.


class People(models.Model):

    name = models.CharField(max_length=20)
    age = models.IntegerField()

 

生成迁移脚本:python manage.py makemigrations 子应用名,生成migrations文件夹,里面是迁移脚本

 

 执行迁移脚本:python manage.py migrate 子应用名

执行后可看到生成的DB,如果没有sqlite驱动,按提示下载

 

 

 

from django.db import models


class People(models.Model):
    """
    a.定义模型类必须继承Model或者Model子类,一个模型类相当于一个table
    b.定义的类属性(Field对象)为表中的字段信息
    c.默认表名为子应用名_模型类名小写
    d.默认会自动创建一个id主键(自增、非空)
    e.生成迁移脚本:python manage.py makemigrations 子应用名
    f.生成的迁移脚本会自动放置到子应用的migrations目录中
    g.执行迁移脚本:python manage.py migrate 子应用名
    """
    name1 = models.CharField(max_length=20)
    age = models.IntegerField()


class Projects(models.Model):

    # 一个数据库模型类中只允许定义一个设置了primary_key=True的字段
    # 一旦某个字段设置了primary_key=True,那么ORM框架就不会自动创建id主键
    # num = models.IntegerField(primary_key=True)
    id = models.AutoField(primary_key=True, verbose_name=\'id主键\', help_text=\'id主键\')

    # a.CharField指定varchar类型
    # b.CharField必须得设置max_length参数,指定最大长度
    # c.verbose_name与help_text指定中文的描述,在admin后台站点以及在接口文档平台中会使用到
    # d.unique=True设置唯一约束,默认unique=False
    name = models.CharField(verbose_name=\'项目名称\', help_text=\'项目名称\', max_length=20,
                            unique=True)
    leader = models.CharField(verbose_name=\'项目负责人\', help_text=\'项目负责人\', max_length=10)

    # e.default指定当前字段的默认值
    is_execute = models.BooleanField(verbose_name=\'是否开展\', help_text=\'是否开展\', default=True)
    # f.null指定当前字段是否允许保持null空值
    # g.blank指定前端在创建数据时是否允许不输入
    desc = models.TextField(verbose_name=\'项目描述信息\', help_text=\'项目描述信息\',
                            null=True, blank=True, default=\'\')

    # DateTimeField指定日期时间类型
    # a.auto_now_add=True,在创建一条数据时,会自动将当前时间赋值给create_time,只修改一次
    # b.auto_now=True,每次在更新数据时,会自动将当前时间赋值给update_time,只要修改就会自动更新
    create_time = models.DateTimeField(auto_now_add=True, verbose_name=\'创建时间\', help_text=\'创建时间\')
    update_time = models.DateTimeField(auto_now=True, verbose_name=\'更新时间\', help_text=\'更新时间\')

    class Meta:
        # a.可以在Meta内部类中修改当前表的元数据信息
        # b.指定创建的数据表名称
        db_table = \'tb_projects\'
        # c.指定创建的数据表中文描述信息
        verbose_name = \'项目表\'
        verbose_name_plural = \'项目表\'

    def __str__(self):
        return self.name

 

 

from django.db import models


# 表与表之间有哪些关联关系?
# Projects与Interfaces表,一对多的关系
# 学生表与学生详细信息表,一对一的关系
# 学生表与课程表,多对多的关系

# 一条项目数据:id为1的测试开发平台项目
# 多条接口数据:id为1的登录接口、id为2的注册接口、id为3的生成用例的接口
class Interfaces(models.Model):
    id = models.AutoField(primary_key=True, verbose_name=\'id主键\', help_text=\'id主键\')
    name = models.CharField(verbose_name=\'接口名称\', help_text=\'接口名称\', max_length=15, unique=True)
    tester = models.CharField(verbose_name=\'测试人员\', help_text=\'测试人员\', max_length=10)
    # a.可以使用ForeignKey在从表中指定外键字段,在一对多关系中‘多’的那侧添加外键字段
    # b.ForeignKey第一个参数,需要指定关联的父表,往往使用\'子应用名.父表模型类名\'
    # c.必须指定on_delete级联删除策略
    # d.级联删除策略有如下种类:
    # CASCADE:当父表数据删除之后,对应的从表数据会被自动删除
    # SET_NULL:当父表数据删除之后,对应的从表数据的外键字段会被自动设置为null
    # PROTECT:当父表数据删除时,如果存在对应的从表数据,那么会抛出异常
    # SET_DEFAULT:父表数据删除之后,对应的从表数据的外键字段会被自动设置为default参数指定的值
    # 创建创建数据表时,会自动创建projects_id作为字段名,用于存放父表外键值
    # ForeignKey: 一对多
    # OneToOneField:一对一
    # ManyToManyField:多对多
    projects = models.ForeignKey(\'projects.Projects\', on_delete=models.CASCADE)
    create_time = models.DateTimeField(auto_now_add=True, verbose_name=\'创建时间\', help_text=\'创建时间\')
    update_time = models.DateTimeField(auto_now=True, verbose_name=\'更新时间\', help_text=\'更新时间\')

    class Meta:
        db_table = \'tb_interfaces\'
        verbose_name = \'接口表\'
        verbose_name_plural = \'接口表\'

    def __str__(self):
        return self.name

 

添加数据

 

一、创建(C)
方式一:
a.直接使用模型类来创建模型对象
b.必须调用save()方法才会执行sql语句(提交)
one_project = Projects(name=\'XXX金融项目11\', leader=\'大脑斧\', desc=\'这是一个描述\')
one_project.save()

方式二:
a.可以使用模型类.objects为manager对象
b.可以使用manager对象.create方法(关键字参数)
c.无需调用save方法,会自动提交
one_project = Projects.objects.create(name=\'XXX在线商城项目11\', leader=\'开始\', desc=\'xxx描述\')

添加子表数据
Interfaces(name=\'登录接口\', tester=\'Aaron\', projects_id=one_project.id)
one_interface = Interfaces(name=\'登录接口\', tester=\'Aaron\', projects=one_project)
one_interface = Interfaces.objects.create(name=\'登录接口\', tester=\'Aaron\', projects=one_project)

二、更新数据(U)
方式一:
a.所有的模型类,会有一个默认的objects属性,是一个manager对象
b.获取需要修改的模型类对象之后,重写相应的字段
c.必须得调用save()方法,才会提交
one_project = Projects.objects.get(id=5)
one_project.name = \'XXX在线商城项目22\'
one_project.save()

方式二:
a.先将待修改的数据取出(查询集对象)
b.然后调用update()方法
c.无需调用save()方法,会自动提交
qs = Projects.objects.filter(id=5).update(leader=\'唯一\')

三、查询(R)
1.读取多条数据
a.使用模型类.objects.all()
b.返回QuerySet对象,类似于列表,但不是列表
c.QuerySet对象,惰性查找,只有需要用到数据(len、取值、for)时,才会执行sql语句
d.QuerySet对象中为模型类对象(数据)
project_qs = Projects.objects.all()
for pro in project_qs:
print(pro.name)
print(list(project_qs))

2.读取一条数据
方式一:
a.可以使用模型类.objects.get()
b.如果查询的结果为空,那么会抛出异常
c.如果查询的结果超过一条数据,也会抛出异常
d.get方法,往往会使用主键或者唯一键作为查询条件
e.返回模型类对象(数据)
one_project = Projects.objects.get(id=1)
pk为django模型类内置的一个属性,是主键的别名
one_project = Projects.objects.get(pk=1)
one_project = Projects.objects.get(Projects.objects.get(leader=\'大脑斧\'))

方式二:
a.模型类.objects.filter方法
b.返回QuerySet对象
c.如果查询的结果为空,那么会返回空的QuerySet对象
d.如果查询的结果超过一条,也会返回多条结果所在的QuerySet对象
e.字段名__查询类型=具体值
f.查询类型种类?
gt >
gte >=
lt <
lte <=
in 对处于列表中的值进行过滤
contains 包含
icontains 包含,忽略大小写
startswith 以xxx开头
istartswith 以xxx开头,忽略大小写
endswith 以xxx结尾
iendswith 以xxx结尾,忽略大小写
isnull 是否为空

qs = Projects.objects.filter(id=4)
qs = Projects.objects.filter(pk=4)
qs = Projects.objects.filter(id__exact=4)
qs = Projects.objects.filter(id__in=[1, 3])
qs = Projects.objects.filter(name__contains=\'金融\')
qs = Projects.objects.filter(update_time__gt=\'2021-01-18\')

exclude与filter为反向关系
qs = Projects.objects.filter(id__gt=3)
qs = Projects.objects.exclude(id__lte=3)

取出某个项目所属接口名称中包含\'登录\'的项目
关联查询
关联模型类名小写__关联模型类中的字段名__查询类型=具体值
关联模型类名1小写__关联模型类1中的外键名__关系模型类2中的字段名__查询类型=具体值
qs = Projects.objects.filter(interfaces__name__contains=\'登录\')
qs = Interfaces.objects.filter(name__contains=\'登录\')
使用外键字段,可以取出父表中对应的模型类对象
one_project = qs[0].projects
return HttpResponse(one_project)


QuerySet查询集的特性
1、惰性查询
2、链式调用
a.查询集对象可以多次调用filter方法,进行过滤
b.多个filter中的过滤条件为与的关系
c.在一个filter方法中,可以写多个条件,每个条件之间以“逗号”分割,每个条件为与的关系

3、哪些操作会让查询集执行sql语句? 查询集支持哪些操作?
a.通过数字索引取值,但不支持负值索引
b.支持切片操作
c.支持.first()方法,可以取出查询集中的第一个元素,为模型类对象
d.支持.last()方法,可以取出查询集中的最后一个元素,为模型类对象
e.支持len(查询集对象),获取查询集的长度,也可以使用.count()方法
f.支持.exists()方法,来判断查询集中是否有元素,如果有元素,那么返回True,否则返回False
g.支持for循环迭代
qs = Projects.objects.filter(name__contains=\'商城\')

逻辑关系
a.与的关系
one = qs.filter(leader=\'唯一\')
qs = Projects.objects.filter(name__contains=\'商城\').filter(leader=\'唯一\')
qs = Projects.objects.filter(name__contains=\'商城\', leader=\'唯一\')

b.或的关系
可以使用Q对象来实现逻辑关系查询
多个Q对象之间使用|,为或的关系
多个Q对象之间使用&,为与的关系
qs = Projects.objects.filter(Q(name__contains=\'商城\') | Q(leader=\'大脑斧\'))

排序操作
a.默认是以id主键升序来排序的
b.查询集对象.order_by(\'字段名1\',\'字段名2\')
c.默认指定的字段名为升序
d.可以在字段名的前面添加-,代表以降序来排序

删除操作(D)
方式一:
调用模型类对象中的delete()方法
one_project = Projects.objects.get(pk=1)
one_project.delete()

方式二:
使用查询集对象.delete(),可以将查询集中的所有数据删除
one = Projects.objects.filter(name__contains=\'商城\').delete()
names = [\'登录接口\', \'注册接口\', \'订单接口\', \'购物车接口\']
for i in range(20):
random_str = \'\'.join(random.sample(string.ascii_letters + string.digits, 8))
interface_name = random.choice(names) + random_str
Interfaces.objects.create(name=interface_name, tester=\'Aaron\', projects_id=random.choice([2, 3, 4, 5]))

a.values和annotate为固定用法
b.聚合运算需要设置为从表名小写
c.使用外键id作为关联条件,同时会把外键id作为分组条件
d.默认查询id和聚合运算的值
e.聚合运算的别名会自动设置为从表名小写__聚合函数名小写
f.可以给聚合运算设置关键词参数,会作为聚合运算的别名
qs = Projects.objects.values(\'id\').annotate(Count(\'interfaces\'))
qs = Projects.objects.values(\'id\').annotate(interfaces=Count(\'interfaces\'))
qs = Projects.objects.annotate(interfaces=Count(\'interfaces\'))
return HttpResponse(\'\')



Django之models查询参数及聚合函数

分类:

技术点:

相关文章:

  • 2021-12-30
  • 2022-12-23
  • 2022-03-02
  • 2021-11-28
  • 2022-02-11
  • 2022-01-18
  • 2021-08-21
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-12-08
  • 2022-12-23
  • 2021-11-27
  • 2022-02-02
相关资源
相似解决方案