Django(3)|Django中的ORM+后台站点管理

一、ORM 对象关系映射

1.原理

Django鼓励开发人员进行相对独立的模块开发,这种开发模式在工作中被称为:解耦合,就是指在开发中将项目看成几个独立的模块进行开发,降低模块之间的耦合性。在这种思路下,django数据开发采用了mvc和mvt设计模式,和ORM机制

  • orm将数据库中的表名映射为类名,将字段映射为属性,可以操作类方法,类属性快速操作数据库
  • orm可以使用我们创建好的模型,帮我们创建表,无需关心具体使用的是那种数据库

2.创建模型
在models.py创建模型
在这里插入图片描述

3. 检查(不常用)

在数据迁移之前,确定配置是否完成

python manage.py check

在这里插入图片描述

4.同步表结构和数据迁移

同步表结构

python manage.py makemigrations

在这里插入图片描述
数据迁移

python manage.py migrate

在这里插入图片描述

这个时候就能看到sqlite3数据库生效了
在这里插入图片描述

但是我们注意到表名是自建的,我们修改一下
在这里插入图片描述

二、ORM字段类型

1.字段类型
关于字段类型基本上和数据库字段类型相同

类型含义
CharFieldvarchar类型,需要指定长度
IntegerField整型
DecimalField浮点型,需要指定最大长度和小数点位数
DateField日期,例如datetime
ImageField图片
ForeignKey做外键

而ForeignKey 做外键又有以下几个参数

①to 设置关联表
②to_field 关联表要关联的键名,默认为关联表中的id,可以不写
③on_delete 当删除关联表中的数据的时候,从表做什么行为,
 	(1)CASCADE  当关联表中数据删除的时候,外键所在表中的数据也会被删除
 	(2)SET_NULL  当关联表中数据删除的时候,外键所在表中的外键设置为空
 	(3)SET_DEFAULT  当关联表中数据删除的时候,外键所在表中的外键设置一个默认值
 	(4)PROTECT 关联保护,当关联表的数据被删除的时候,报异常,
 	(5)DO_NOTHING  当关联表中数据删除的时候,外键所在的表不做任何事情

2.字段属性

属性备注
max_length最大长度
verbose_name备注,站点管理中用于显示字段为中文
max_digits浮点型最大长度
decimal_places小数点位数
auto_now= True获取的是当前时间
null= True可为空,默认是不为空

3.元数据

属性备注
db_table修改表的名字长度
verbose_name备注,站点管理中用于显示模型名字为中文,会出现s
verbose_name_plural显示复数名称(站点管理处)
ordering= [‘-age’]指定排序

三、ORM的单表操作

准备工作:我们重新在models中创建一个类并进行数据迁移

from django.db import models
# 创建学生表
class Person(models.Model):
    # id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32, verbose_name='名字')
    age = models.IntegerField(verbose_name='年龄')
    height = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='身高', null=True)  # 长度为5,两位小数
    birthday = models.DateField(verbose_name='生日')

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'person'
        verbose_name = '用户'
        verbose_name_plural = verbose_name  # 显示的是后台模块的名字

1.添加数据

方法使用
save需要声明model类的对象,然后可以使用对象.属性添加,也可以使用类中声明时候直接添加属性,注意最后需要对象.save()保存
create借助objects.create(属性1,属性2)添加

使用
在这里插入图片描述

运行
在这里插入图片描述
数据库生效
在这里插入图片描述

2.查询数据

常用查询方法

使用功能
all()查询所有结果
filter(**kwargs)它包含了与所给筛选条件相匹配的对象
get(**kwargs)返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
exclude(**kwargs)它包含了与所给筛选条件不匹配的对象
values(*field)返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
values_list(*field)它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
order_by(*field)对查询结果排序
reverse()对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)
distinct()从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。)
count()返回数据库中匹配查询(QuerySet)的对象数量。
first()返回第一条记录
last()返回最后一条记录
exists()如果QuerySet包含数据,就返回True,否则返回False

对于返回多个结果的一般返回QuerySet对象(可迭代对象),这里稍微总结一下

类型备注
返回QuerySet对象的方法all()、filter()、exelude()、order_by()、reverse()、distinct()
特殊的QuerySet1.values() :返回一个可迭代的字典序列 2. values_list() 返回一个可迭代的元祖序列
返回具体对象的方法get()、first()、last()
返回布尔值的方法exists()
返回数字的方法count()

​ 使用举例

views.py

def getPerson(request):
    # 1.all 方法
    # data = models.Person.objects.all()
    # print (data)
    # print (data[0].name)
    # print (data[0].age)
    # print (data[0].height)
    # for one in data:
    #     print('生日:', one.birthday)
    #     print('名字:', one.name)
    
    # --------------------------------------------------------------------
    # 2.filter()方法,筛选条件,但是返回的是一个queryset类型
    # data = models.Person.objects.filter(birthday='1912-12-22')
    # for i in data:
    #     print(i.age)
    # -----------------------------------------------------------------------
    # 3.exclude()方法和filter方法相反,返回的是非符合条件的
    # data = models.Person.objects.exclude(birthday='1912-12-22')
    # for i in data:
    #     print(i.name)
    # --------------------------------------------------------------------
    # 4.get()方法,筛选条件,一般参数为主键,只能筛选唯一符合条件的
    # data=models.Person.objects.get(birthday='1912-12-22')
    # print(data)
    # --------------------------------------------------------------------
    # 5.first()和last()方法,将选出第一条和最后一条数据
    # data=models.Person.objects.filter(age=11).first()
    # print(data)
    # data=models.Person.objects.filter(age=11).last()
    # print(data)
    # --------------------------------------------------------------------
    # 6.order_by 排序,默认升序,降序在参数前加-
    # data=models.Person.objects.order_by('-age')
    # for i in data:
    #     print(i.name)
    # ---------------------------------------------------------------------
    # 7.values,会将查询到的对象以字典形式将详细数据查询出来,并放在列表中
    # data=models.Person.objects.all().values()
    # print(data)
    # ---------------------------------------------------------------
    # 8.exists(),查询符合条件的数据是否存在,返回true或false
    # data=models.Person.objects.filter(age=33).exists()
    # print(data)
    # -----------------------------------------------------------------
    # 9.count()记录符合条件的条数
    # data=models.Person.objects.all().count()
    # print(data)

然后还有其他的双下划线查询方法

下划线查询法用法
__gt
__lt
__gte
__lte
__in包含
__range范围
__isnull为空
startswitch开始,类似 like ‘a%’
endswitch结束,类似 like ‘%a’
contains类似 %a% ,对大小写敏感
icontains类似 %a% ,对大小写不敏感

举例用法:

def getPerson(request):
    #__gt大于   __lt小于  __gte大于等于 __lte  小于等于
    # data=models.Person.objects.filter(age__gt=20)
    # print(data[0].name)
	# ---------------------------------------------------------
    #__in包含,exclude不包含,range范围
    # data=models.Person.objects.filter(age__in=(22,))
    # for i in data:
    #     print(i.name)
    
    # data = models.Person.objects.exclude(age__in=(22,))
    # for i in data:
    #     print(i.name)
    
    # data=models.Person.objects.filter(age__range=(15,30))
    # for i in data:
    #     print(i.name)
    
    # ---------------------------------------------------------
    # 查询身高为__isnull
    # data=models.Person.objects.filter(height__isnull=True)
    # for i in data:
    #     i.height=1.11
    #     i.save()

	# ---------------------------------------------------------
    #查询开头的startswitch和查询结尾的endswitch
    # data=models.Person.objects.filter(name__startswith='讲师')#like '讲师%'
    # print(data[0].name)
    # data=models.Person.objects.filter(name__endswith='罗')
    # print(data[0].name)
	
	# ---------------------------------------------------------
    #包含的contains类似like %a%   对大小写敏感    icontains 对大小写不敏感
    data=models.Person.objects.filter(name__contains='师')
    print(data[0].name)
    return HttpResponse('查询数据成功')

3.修改数据

views.py

def updatePerson(request):
    #1.save(),先查要修改的数据,然后直接用对象.属性=修改值,如果查询的数据为多个需要用遍历修改
    # data=models.Person.objects.get(id=2)
    # data.height=233.34
    # data.save()

    #--------------------------------------------------------------
    #2.update(),先查后更新
    models.Person.objects.filter(id=3).update(name='孙悟空') # 更新什么写什么字段
    return HttpResponse('修改数据成功')

4.删除数据

views.py

def delPerson(request):
    models.Person.objects.get(id=6).delete()
    return HttpResponse('删除数据成功')

四、多表查询(一对多)

准备工作:创建多表,并进行数据迁移
在这里插入图片描述
models.py
在这里插入图片描述

1.增加数据

views.py

# 方法1--------------------------------------------------
# 增加出版社
# Publish.objects.create(name='清华出版社',address = '北京')
# Publish.objects.create(name='中国出版社',address = '北京朝阳')
# Publish.objects.create(name='河南出版社',address = '洛阳')

# 增加书
# Book.objects.create(name='python入门',publish_id = 1)

# 将出版社和书关联
# publish = Publish.objects.get(name='中国出版社')
# Book.objects.create(name='python入门', publish_id=publish.id)

# 方法2--------------------------------------------------
# Book.objects.create(name='python核心编程',publish = Publish.objects.get(name='中国出版社'))

# 方法3--------------------------------------------------
# 正向操作    从外键所在的表到主表叫正向
book = Book()
book.name= '笨办法学python'
book.publish = Publish.objects.get(name='河南出版社')
book.save()

# 反向操作  从主表到从表 叫反向
publish_obj = Publish.objects.get(name="中国出版社")
publish_obj.book_set.create(name='pythonWeb开发')

2.查询数据

views.py

# 方法1--------------------------------------------------
# publish = Publish.objects.get(name="中国出版社")
# book = Book.objects.filter(publish_id=publish.id).all()
# for x in book:
#     print (x.name)

# 方法2--------------------------------------------------
# 正向查询  从外键所在的表到主表叫正向
# 查询  pythonWeb开发 属于哪一个出版社
# book = Book.objects.filter(name='pythonWeb开发').first()
# print (book.name)
# print (book.publish.name)

# 方法3--------------------------------------------------
# 反向查询 从主表到从表  叫 反向查询     _set
publish = Publish.objects.get(name='中国出版社')
book = publish.book_set.all()
print (book)

3.更新数据

views.py

# 一对多更新数据
def updatemore(request):
    # save
    # book=models.Book.objects.get(id=2)
    # book.publish=models.Publish.objects.get(name='清华出版社')
    # book.save()
    # #upadate
    # models.Book.objects.update(name='python',publish=models.Publish.objects.get(id=3))

    #set
    # 反向,类似数据库中的update
    publish = models.Publish.objects.get(name='蓝翔出版社')
    book = models.Book.objects.get(id=2)
    book2 = models.Book.objects.get(id=1)
    publish.book_set.set([book, book2])

    return HttpResponse('修改数据成功')

4.删除数据

views.py

# 一对多删除数据
def delmore(request):
    # 一般先删除从表再删除主表,根据模型类里的外键设置决定
    models.Book.get(id=2).delete()
    models.Publish.get(id=2).delete()
    return HttpResponse('删除数据成功')

五、多表查询(多对多关系)

准备工作:建表+数据迁移
在这里插入图片描述
models.py

class Person(models.Model):
    # id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32,verbose_name="姓名")
    age = models.IntegerField(verbose_name="年龄")
    height = models.DecimalField(max_digits=5,decimal_places=2,verbose_name="身高",null=True)
    birthday = models.DateField(verbose_name="生日",auto_now=True)

    def __str__(self):
        return str(self.name)

    class Meta:
        db_table = 'person'
        verbose_name = "用户"
        verbose_name_plural = verbose_name
        # ordering= ['-age','id','name']

class Teacher(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField(default=0)
    gender = models.CharField(max_length=8)
    person = models.ManyToManyField(to=Person)
    class Meta:
        db_table = 'teacher'

1.添加数据

views.py

# 多对多添加
def addmanytomany(request):
    # 添加老师
    # models.Teacher.objects.create(name='僵尸王宗涛',gender=1)
    # models.Teacher.objects.create(name='僵尸张环宇',gender=0)
    # models.Teacher.objects.create(name='僵尸温俊鹏',gender=1)

    # 正向操作
    # 添加新学生,和僵尸王宗涛关联
    # teacher=models.Teacher.objects.get(name='僵尸王宗涛')
    # teacher.person.create(name='孙悟空',age=3)

    # 老学生关联温老师,需要将两个数据都查出来,并使用add()
    # teacher=models.Teacher.objects.get(id=3)
    # person=models.Person.objects.filter(name='泰罗').first()
    # teacher.person.add(person)

    # 反向操作
    teacher = models.Teacher.objects.get(id=2)
    person = models.Person.objects.get(id=1)
    person.teacher_set.add(teacher)
    return HttpResponse('添加成功')

2.查询数据

views.py

# 多对多查询
def getmanytomany(request):
    # 寻找id为3的老师教的所有学生
    teacher = models.Teacher.objects.get(id=3)
    person = teacher.person.all()
    print(person.values())
    # 根据学生查老师
    person = models.Person.objects.get(id=6)
    teacher = person.teacher_set.all()
    print(teacher.values())

    return HttpResponse('查询成功')

3.修改数据

# 多对多修改
def updatemanytomany(request):
    # 正向修改
    # 将讲师王宗涛的学生改为234,set后边放列表,列表里传入更改的关联数据
    # teacher=models.Teacher.objects.get(id=1)
    # person1=models.Teacher.objects.get(id=2)
    # person2=models.Teacher.objects.get(id=3)
    # person3=models.Teacher.objects.get(id=4)
    # teacher.person.set([person1,person2,person3])

    # 反向
    person = models.Person.objects.get(id=2)
    teacher1 = models.Teacher.objects.get(id=3)
    teacher2 = models.Teacher.objects.get(id=2)
    person.teacher_set.set([teacher1, teacher2])

    return HttpResponse('修改成功')

4.删除数据

# 多对多删除
def delmanytomany(request):
    # remove 解除关系
    # 正向
    # teacher=models.Teacher.objects.get(id=1)
    # person=models.Person.objects.get(id=3)
    # teacher.person.remove(person)

    # 反向
    # person=models.Person.objects.get(id=4)
    # teacher=models.Teacher.objects.get(id=1)
    # person.teacher_set.remove(teacher)

    # del删除
    models.Person.objects.get(id=2).delete()
    return HttpResponse('删除成功')

六、聚合函数和F/Q对象

1.聚合函数

求点最大值最小值平均值什么的

# 聚合函数
from django.db.models import Max, Min, Count, Avg, Sum


def juhe(request):
    data = models.Person.objects.all().aggregate(Avg('age'))
    print(data)  # 显示的是queryset
    data = models.Person.objects.all().aggregate(Avg('age'), sum('age'))
    print(data)  # 显示的是queryset

    return HttpResponse('聚合查询')

2.F对象和Q对象

  • F对象: 用于比较同一个模型中的两个字段的值
  • Q对象:用于处理多条件中的逻辑关系 and or not
from django.db.models import F, Q


def Ftest(request):
    # 查询book中销量大于库存的
    book = models.Book.objects.filter(xiaoliang__gt=F('kucun')).all()
    print(book)
    return HttpResponse('f对象')


def Qtest(request):
    # and
    book = models.Book.objects.filter(Q(xiaoliang=20) & Q(kucun=50))
    print(book)
    book = models.Book.objects.filter(xiaoliang=20, kucun=50)
    print(book)
    # or
    book = models.Book.objects.filter(Q(xiaoliang=20) | Q(kucun=50))
    print(book)
    # not
    book = models.Book.objects.filter(~Q(xiaoliang=20) | ~Q(kucun=50))
    print(book)
    return HttpResponse('q对象')

七、后台站点管理

1.命令行输入创建超级用户,并输入用户名和邮箱和密码

python manage.py createsuperuser

2.进入后台站点

运行项目,地址加入admin
在这里插入图片描述

3.安装模型类
在创建的类中将类名传入admin
在这里插入图片描述

4.使用后台管理可以管理数据
在这里插入图片描述

5.修改站点管理后台为中文
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张烫麻辣亮。

谢谢老板支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值