ORM——属性操作

对象(数据)操作

增加

  • objects.create(name)

向数据库插入一个属性。

models.user_name.objects.create(name)
  • set

向所关联的表中进行数据添加

rece_data = request.POST
add_stu_name = models.stu_user.objects.create(stu_name=rece_data.get('stu_name'),
                                              stu_age=rece_data.get('stu_age'),
                                              stu_sex=rece_data.get('sex'))
add_stu_name.cla_stu_id.set(rece_data.getlist('cla_name'))

删:

对表内容进行删除

models.stu_user.objects.filter(pk=del_pk).delete()
#stu_user为表名称,对id进行删除

查:

  • objects

使用objects内的属性进行查询

ret = models.User.objects.xxx

常用查询语句13条

ret = models.Book.objects.all()   #获取所有的数据——QuerySet对象列表
ret = models.Book.objects.get(pk=1)    #获取不到、获取多个将报错
ret = models.Book.objects.filter()   #获取所有的数据——QuerySet对象列表
ret = models.Book.objects.exclude(pk=1)  # 过滤满足条件的数据——QuerySet对象列表
ret = models.Book.objects.values()   #获取对象所有的字段和字段的值——QuerySet[{},{}]字典列表
ret = models.Book.objects.values('nid',)   #获取对象特定字段和字段的值——QuerySet[{},{}]字典列表
ret = models.Book.objects.values_list()   #获取对象所有的字段和字段的值——QuerySet[(),()]元素列表
ret = models.Book.objects.all().order_by('nid')  #取所有的数据并进行排序,默认升序,需要降序('-nid'),——QuerySet对象列表
ret = models.Book.objects.all().order_by('nid','-username')  #取所有的数据并进行排序,针对多个值进行排序。
ret = models.Book.objects.all().distinct()  #获取所有的数据,并进行去重处理。需要提取的数据完全相同才可以去重——QuerySet对象列表
ret = models.Book.objects.all().count()   #获取所有的数据,并进行计数。和len一样。
ret = models.Book.objects.all().first()    #获取所有数据,并提取第一个元素,没有即None
ret = models.Book.objects.all().last()    #获取所有数据,并提取最后一个元素,没有即None
ret = models.Book.objects.filter(pk=1).exists()   #判断数据是否存在,存在=True,不存在=False
ret = models.Book.objects.all().update(age=60)   #获取所有对象,将age值全部更改为60
models.Book.objects.all().update(price=F("price")+30)   #多去所有对象,将price逐一提取并+30
  • filter

  1. 推荐使用
  2. 有几个获取几个,如果没有将返回空
  3. 返回的是QuerySet数据类型,如需要再返回对象,那么就再最后.first()
  4. 不至于下面那些会报错
  5. 可以直接对用户名和密码进行判断
  6. models是要将mysql的app进行导入。
from books_app import models
def set(request):
    ret = models.User.objects.filter(username='xin',password='123')
    print(ret.username,ret.password)
    return HttpResponse('ok')
  • all

  1. 获取表中所有数据
  2. class_name为创建的class名称。也就是在mysql中的表名称。
  3. 将获取对象叫做QuerySet对象。
  4. 如果没有数据,将会报错
def set(request):
    ret = models.User.objects.all() #获取QuerySet对象
    for i in ret:
        print(i.username,i.password)
    return HttpResponse('ok')
  • get

  1. 获取某一个信息
  2. 返回相应的对象
  3. 获取值时,必须是有且只有一个,没有值或者有多个值时将会报错。
def set(request):
    ret = models.User.objects.get(username='xin')  #查询get中写入的字段和字段值
    print(ret.username,ret.password)  #如有值将进行打印
    return HttpResponse('ok')
  • xx_set(反向查询)&related_name

  1. 使用情况,在使用关联中的一对多的情况中的被关联对象查询关联对象信息时使用
class Publisher(models.Model):
    name = models.CharField(max_length=32,verbose_name='名称')
    def __str__(self):
        return self.name
    
class Book(models.Model):
    title = models.CharField(max_length=32)
    pub = models.ForeigbKey(Publisher,related_name='books',on_delete=models.CASCADE)
    def __str__(self):
        return self.title
#正向查询
obj = models.Book.objects.get(name='zhao')
#反向查询
pub_obj = models.Class_name.objects.get(pk=1)
fobj = pub_obj.class_name_set.all()       #class_name小写_set
fobj = pub_obj.books.all()               #需要在关联中指定related_name='books'
  • 双下划线查询

class Publisher(models.Model):
    name = models.CharField(max_length=32,verbose_name='名称')
    def __str__(self):
        return self.name
    
class Book(models.Model):
    title = models.CharField(max_length=32)
    pub = models.ForeigbKey(Publisher,related_name='books',on_delete=models.CASCADE)
    def __str__(self):
        return self.title
#单表双下划线查询
#__gt:大于某个值的
data = models.Book.objects.filter(pk__gt=1)  #pk大于1的
#__lt:小于某个值的
data = models.Book.objects.filter(pk__lt=1)  #pk小于1的
#__gte:大于等于某个值的
data = models.Book.objects.filter(pk__gte=1)  #pk大于等于1的
#__lte:小于等于某个值的
data = models.Book.objects.filter(pk__lte=1)  #pk小于等于1的
#__range:获取范围值
data = models.Book.objects.filter(pk__range=[2,4])  #获取2-4的值,包含2和4
#__in:获取and值
data = models.Book.objects.filter(pk__in=[2,4])  #获取2and4的值
#__contains:模糊查询
data = models.Book.objects.filter(name__contains='x')  #获取name中有x的值,区分大小写,要忽略就(name__icontains='x')
#__startwith:某字段开头查询
data = models.Book.objects.filter(name__startwith='x')  #获取name中以x开头的值,区分大小写,要忽略就(name__istartwith='x')
#__endwith:某字段结尾查询
data = models.Book.objects.filter(name__endwith='x')  #获取name中以x结尾的值,区分大小写,要忽略就(name__iendwith='x')
#__year:获取某一年份值
data = models.Book.objects.filter(pk__year='2019')  #获取某一年份的值,只有年份,如需要其他使用contains。
#__isnull:获取数据为空的值
data = models.Book.objects.filter(pk__isnull=True)  #获取某个值中的数据为null的值。不为空则:(pk__isnull=False)
  • F比较查询

  1. 用于比较两个字段的值
  2. 取值并操作,而不是更改某些值
from django.db.models import F
#查询book内,commnet大于keep_num的
models.Book.objects.filter(commnet_num__gt=F('keep_num'))

#提取book中,所有price字段,并进行+30操作
models.Book.objects.all().update(price=F("price")+30)
#如果单独使用update,那么就等于更改,而不是逐一+30操作


#取小于comment的keep_num的值,并提取出来进行*2
models.Book.objects.filter(commnet_num__lt=F('keep_num')*2)
  • Q是与非查询

  1. Q为条件筛选工具
  2. 用‘|’进行分开,表示or的关系
  3. 用‘&’分开,表示and的关系
  4. 用‘~’分开,表示not的关系
#查找book中authors是小仙女或小魔女的
models.Book.objects.filter(Q(authors__name="小仙女")|Q(authors__name="小魔女"))

#查找book中authors是小仙女或小魔女的,并且age=27的
models.Book.objects.filter(Q(Q(authors__name="小仙女")|Q(authors__name="小魔女"))& Q(authors__age='27'))

#查找book中authors是小仙女或不是小魔女的,并且age=27的
models.Book.objects.filter(Q(Q(authors__name="小仙女")|~Q(authors__name="小魔女"))& Q(authors__age='27'))

外键&多对多操作

关系管理器是在一对多或多对多中关联上下文使用的管理器。

它存在于下面两种情况:

  1. 外键关系
  2. 多对多关联关系

外键指的是一对多的关系,需要注意的:

  1. 其中set和add只能用于对象方式操作。
  2. 如果对象中没有设置允许为空字段(null=True),那么默认没有remove和clear方法。

简答来说,就是当点后面的对象可能存在多个的时候就可以使用。

zhao =  models.Author.objects.get(pk=1)   
print(zhao.books)   #打印关系管理对象,因为books存在多个,那么就会是关系管理对象。
print(zhao.books.all)   #打印所有pk=1所关联的books

两种查询方式:

  1. 根据对象查询
  2. 根据ID查询

基础环境:

class Book(models.Model):
    title=models.CharField(max_length=32)
    def __str__(self):
        return self.title
    
class Author(models.Model):
    name = models.CharField(max_length=32,)
    books = modles.ManyToManyField(Book)
zhao =  models.Author.objects.get(pk=1)  
print(zhao.books)   #打印关系管理对象
print(zhao.books.all)   #打印所有pk=1所关联的books

#外键反向查询,在没有所关联的对象那里查询,在Book里插Author
qian = models.Book.objects.get(title='xxx')
print(qian.author_set)#打印关系管理对象
print(qian.author_set.all) #打印所有title='xxx'所关联的author信息
print(qian.authors.all)#如果指定related_name,那就直接使用related_name的名称即可

#多对多反向查询
#1. 对某个publisher查找书
data = models.Book.objects.filter(pub__name='pub_name')
#2. 查找某个数的出版社
ret = models.Publisher.objects.filter(book__title='title_name')

关系管理对象的方法:

zhao =  models.Author.objects.get(pk=1)  
#all
print(zhao.books.all)   #打印所有pk=1所关联的books
#set
print(zhao.books.set([1,2,3]))   #添加,将其他已经存在的对应关系删除掉。
print(zhao.books.set(models.Book.objects.filter(pk__in=[1,2,3])))   #对象方式添加
#add
print(zhao.books.add(4,5))   #添加,不会影响已存在的对应关系
print(zhao.books.add(*models.Book.objects.filter(pk__in=[1,2,3])))   #对象方式添加,*代表打散,意义是表示一个一个对象,而之前是一个列表
#create
print(zhao.books.create(title='abc'))   #添加一个新的book,并进行关联
#remove
print(zhao.books.remove(4,5))   #删除
print(zhao.books.remove(*models.Book.objects.filter(pk__in=[1,2,3])))   #对象方式删除
#clear
print(zhao.books.clear())   #清除所有关联关系

聚合&分组

聚合

  1. 指将表中一些数据进行整理和分析,所得出的结论。像:最大值,最小值,平均值等。
  2. aggregate()QuerySet 的一个终止子句,意思是说,直接出来的是字典格式了。
  3. 它返回一个包含一些键值对的字典。key为名称是聚合值的标识符,value是计算出来的聚合值
  4. key的名称是按照字段和聚合函数的名称自动生成出来的。

用到的内置函数:

from django.db.models import Avg, Sum, Max, Min, Count

例句:

from django.db.models import Avg, Sum, Max, Min, Count
models.Book.objects.all().aggregate(Avg("price"),max=Max("price"))  #多个,命名都是可以的。

分组

  1.  annotate是分组+聚合的方法,其实annotate可以视为描述,将特定的信息添加到描述内。
  2. 再将得出的结果,放到对象内。再使用values进行查看。
from django.db.models import Avg
# models.需要分组的名称.objects.annotate(命名 = 聚合(以哪个属性进行聚合)).要不要直接出结果('结果名称','结果名称')
models.Dept.objects.annotate(avg=Avg("employee__salary")).values("name", "avg")

#对分组进行筛选条件,然后进行查找和聚合
models.Book.objects.values("publisher__name").annotate(min_price=Min("price"))

#统计不止一个作者的图书
models.Book.objects.annotate(author_num=Count("author")).filter(author_num__gt=1)

其他:

事务

将各种事情联合起来一起做,如果其中一个环节出现问题,那么就全部倒回去。就像给其他人转账一样。

from django.db import transaction    #导入事务
try:   #开启报错提示,并且需要写在with上面
    with transaction.atomic():  #开启事务,在期内即可进行ORM操作
        print('123')
        print(a)
except Exception as e:
    print(e)

Model Meta

用于在指定的表中,进行额外的设置。

class UserInfo(models.Model):
    nid = models.AutoField(primary_key=True)
    username = models.CharField(max_length=32)
 
    class Meta:
        # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
        db_table = "table_name"
 
        # admin中显示的表名称
        verbose_name = '个人信息'
        
        # verbose_name加s
        verbose_name_plural = '所有用户信息'
 
        # 联合索引 
        index_together = [
            ("pub_date", "deadline"),   # 应为两个存在的字段
        ]
 
        # 联合唯一索引
        unique_together = (("driver", "restaurant"),)   # 应为两个存在的字段

直接对数据库进行操作

  1. 在python脚本中调用Django环境
  2. 直接进行的ORM操作,而不用重复的重启项目
#表单模板
class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    username = models.CharField(max_length=32)
    def __str__(self):
        return f'{nid}-{username}'
    
#在python脚本中调用Django环境
import os

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xxx.settings")   #settings所属文件
    import django
    django.setup()

from app01 import models
#可在Book-class中创建__str__进行别名返回

print(ret)
posted @   新兵蛋Z  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2022-02-28 Windows——防火墙允许网络访问
2020-02-28 标准库模块——json&pickle
2020-02-28 标准库模块——shutil模块
点击右上角即可分享
微信分享提示