Django之ORM表操纵

嚴華  论坛元老 | 2024-12-9 21:06:00 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1050|帖子 1050|积分 3150

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
ORM表操纵

1.ORM单表操纵

 首先想操纵表的增删改查,必要先导入这个表,以之前创建的UserInfo表为例,在app下的views.py中导入
  1. from app import models
  2. def query(request):
  3.     new_obj = models.UserInfo(
  4.         id=1,
  5.         name='北北',
  6.         bday='2019-09-27',
  7.         checked=1,
  8.     )
  9.     new_obj.save()
  10.     return HttpResponse('ok')
复制代码
如许就创建了一条记载
增加

方式1:
  1. obj = models.UserInfo(
  2.         id = 2,
  3.         name = '京京',
  4.         bday = '2019-9-27',
  5.         checked = '1',
  6.         )
  7. obj.save()
复制代码
方式2:
  1. ret = models.UserInfo.objects.create(
  2.         name = '欢欢',
  3.         bady = '2019-9-27',
  4.         checked = 0,
  5.         )
  6. print(ret)  #UserInfo object
  7. #ret 是创建的新的记录的model对象
复制代码
ps:批量插入(bulk_create)
  1. obj_list= []
  2. for i in range(20):
  3.     obj = models.Book(
  4.             title=f"西游记{i}",
  5.             price=20+i,
  6.             publish_date=f"2019-09-{i+1}",
  7.             publisher="人民出版社"
  8.             )
  9.     obj_list.append(obj)
  10.    
  11. models.Book.objects.bulk_create(obj_list)  #批量创建
  12. 从前端页面获取到的数据即:request.POST得到的是querydict类型
  13. data = request.POST.dict() --能够将querydict转换成普通的字典
  14. 创建数据时可以:
  15.     models.Book.objects.create(**data)
复制代码
删除

  1. 首先要通过简单查询:filter()  -- 查询结果是queryset类型的数据,里面是一个个的model对象,此数据类型类似于列表
复制代码
方式1:
  1. models.UserInfo.objects.filter(id = 3).delete()
  2. #通过queryset对象删除
复制代码
方式2:
  1. models.UserInfo.objects.filter(id = 3)[0].delete()
  2. #通过model对象删除
复制代码
修改

方式1:
  1. models.UserInfo.objects.filter(id = 2).update(
  2.         name = '英英',
  3.         checked = 0,
  4.         )
  5. #通过queryset对象进行修改,而model对象不能调用update方法
复制代码
方式2:
  1. ret = models.UserInfo.objects.filter(id = 2)[0]
  2. ret.name = '英英'
  3. ret.checked = 0
  4. ret.save()
复制代码
查找

查询API
  1. 1.all()                 查询所有结果,得到的是queryset类型
  2. ret = models.UserInfo.objects.all()
  3. 2.filter(**kwargs)  它包含了与所给筛选条件相匹配的对象,结果也是queryset类型  
  4. ret = models.UserInfo.objects.filter(name='英英' checked=0)
  5. #and多条件查询
  6. #查询条件不能匹配到数据时,不会报错,会返回一个空的query(<QuerySet []>),如果没有写查询条件会获取所有数据,queryset类型的数据还能继续调用filter方法
  7. 3.get(**kwargs)
  8. ret = models.UserInfo.objects.get(name='英英')
  9. #得到的是一个model对象(行记录对象),有且只能有一个
  10. #1.查不到数据会报错:UserInfo matching query does noe exist.
  11. #2.超过一个也会报错:returned more than one UserInfo
  12. 4.exclude(**kwargs)   排除,它包含了与所给筛选条件不匹配的对象,返回的时queryset类型
  13. ret = models.UserInfo.objects.exclude(name='英英')
  14. #1.object能够调用models.UserInfo.objects.exclude(name__startswith=='贝贝')
  15. #2.queryset类型数据能够调用models.UserInfo.objects.all().exclude(name__startswith=='贝贝')
  16. 5.order_by(*filed)  queryset类型的数据来调用,对查询结果排序,默认是按照id来升序排列的,返回值还是queryset类型
  17. ret = models.UserInfo.objects.all().order_by('-grade','id')
  18. #按成绩降序排列,成绩相同的按id升序排列
  19. 6.reverse()  queryset类型的数据来调用,对查询结果反向排序,返回值还是queryset类型
  20. ret = models.UserInfo.objects.all().order_by().reverse()
  21. #数据排序后才能进行反装
  22. 7.count()                 queryset类型的数据来调用,返回数据库中匹配查询(QuerySet)的对象数量。
  23. ret = models.UserInfo.objects.all().count()
  24. 8.first()          queryset类型的数据来调用,返回第一条记录
  25. ret = models.UserInfo.objects.all().first()
  26. 9.last()         queryset类型的数据来调用,返回最后一条记录
  27. ret = models.UserInfo.objects.all().last()
  28. 10.exists()          queryset类型的数据来调用,如果queryset包含数据,就返回True,否则返回False
  29. ret = models.UserInfo.objects.filter(id=9).exists()
  30. #判断返回结果集是不是有数据
  31. 11.values(*filed)          
  32. #queryset类型的数据来调用,返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列,只要是返回的queryset类型,就可以继续链式调用queryset类型的其他的查找方法,其他方法也是一样的。
  33. ret=models.UserInfo.objects.filter(id=2).values('name','bday')
  34. 12.values_list(*filed)
  35. #它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
  36. ret=models.UserInfo.objects.all().values_list('name','bday')
  37. #调用values或者values_list的是objects控制器,那么返回所有数据
  38. #        ret = models.Book.objects.all().values()
  39. #        ret = models.Book.objects.values()  
  40. 13.distinct()   #values和values_list得到的queryset类型的数据来调用,从返回结果中剔除重复记录
  41. ret = models.UserInfo.objects.all().values('checked').distinct()
复制代码
基于双下划线的含糊查询
  1. ret = models.Book.objects.filter(price__gt=35)  #大于
  2. ret = models.Book.objects.filter(price__gte=35) # 大于等于
  3. ret = models.Book.objects.filter(price__lt=35) # 小于等于
  4. ret = models.Book.objects.filter(price__lte=35) # 小于等于
  5. ret = models.Book.objects.filter(price__range=[35,38])
  6. # 大于等35,小于等于38    where price between 35 and 38
  7. ret = models.Book.objects.filter(price__in=[32,35,38])
  8. # price值等于这三个值里面的任意一个的对象   or
  9. ret = models.Book.objects.filter(title__contains='西游记')
  10. # 字段数据中包含这个字符串的数据都要
  11. ret = models.Book.objects.filter(title__icontains="python") # 不区分大小写
  12. ret = models.Book.objects.filter(title__startswith="py")  
  13. # 以什么开头,istartswith  不区分大小写
  14. ret = models.Book.objects.filter(publish_date='2019-09-15')
  15. #按照日期查询
  16. 查询某年某月某日:
  17. ret = models.Book.objects.filter(publish_date__year='2018')
  18. #2018写数字也可以
  19. ret = models.Book.objects.filter(publish_date__year__gt='2018')
  20. #查询出版日期大于2018年的
  21.    
  22. ret = models.Book.objects.filter(publish_date__year='2019',publish_date__month='8',publish_date__day='1')
  23. #查询出版日期为2019-8-1的
  24. 找字段数据为空的双下滑线
  25. ret = models.Book.objects.filter(publish_date__isnull=True) #这个字段值为空的那些数据
复制代码
插入时间问题
  1. 在表的结构里新增列来显示时间
  2. class UserInfo(models.Model):
  3.     id = models.AutoField(primary_key=True)
  4.     name = models.CharField(max_length=10)
  5.     bday = models.DateField()
  6.     checked = models.BooleanField()
  7.     # now = models.DateTimeField(null=True)
  8.     now = models.DateTimeField(auto_now_add=True,null=True)
  9.     #自动插入时间
  10.     now2 = models.DateTimeField(auto_now=True,null=True)
  11.     # 更新记录时,自动添加更新时的时间,创建新纪录时也会帮你自动添加创建时的时间
  12.    
  13. 在提交后进行新增记录:
  14. import datetime
  15. current_date = datetime.datetime.now()
  16. models.UserInfo.objects.create(
  17.         name='妮妮',
  18.         bday=current_date,
  19.         now=current_date,  # 自己手动直接插入时间没有时区问题
  20.         checked=0
  21.     )
  22. #但是如果让这个字段自动来插入时间,就会有时区的问题,auto_now_add创建记录时自动添加当前创建记录时的时间,存在时区问题
  23. now = models.DateTimeField(auto_now_add=True,null=True)
  24. 解决方法:
  25.     settings配置文件中将USE_TZ的值改为False
  26.     USE_TZ = False  
  27.     # 告诉mysql存储时间时按照当地时间来寸,不要用utc时间
  28. 使用pycharm的数据库客户端的时候,时区问题要注意
  29. 更新时的auto_now参数
  30.         # 更新记录时,自动更新时间,创建新纪录时也会帮你自动添加创建时的时间,但是在更新时只有使用save方法的model对象的形式更新才能自动更新时间,有缺陷,放弃
  31.     now2 = models.DateTimeField(auto_now=True,null=True)
复制代码
2.ORM多表操纵

创建模型

表和表之间的关系
  一对一、多对一、多对多 ,用book表和publish表自己来想想关系,想想内里的操纵,加外键束缚和不加外键束缚的区别,一对一的外键束缚是在一对多的束缚上加上唯一束缚。
实例:我们来假定下面这些概念,字段和关系
  作者模型:一个作者有姓名和年事。
  作者具体模型:把作者的详情放到详情表,包罗生日,手机号,家庭住址等信息。作者详情模型和作者模型之间是一对一的关系(one-to-one)
  出版商模型:出版商有名称,地点城市以及email。
  书籍模型: 书籍有书名和出版日期,一本书大概会有多个作者,一个作者也可以写多本书,以是作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一个出版商出版,以是出版商和书籍是一对多关联关系(one-to-many)。
  模型建立如下:
  1. from django.db import models
  2. # Create your models here.
  3. class Author(models.Model):
  4.     '''
  5.     作者表
  6.     '''
  7.    
  8.     name=models.CharField(max_length=32)
  9.     age=models.IntegerField()
  10.   au=models.OneToOneField('AuthorDetail',on_delete=models.CASCADE)
  11.         #就是foreignkey+unique,只不过不需要我们自己来写参数了,并且orm会自动帮你给这个字段名字拼上一个_id,数据库中字段名称为authorDetail_id
  12.     # 与AuthorDetail建立一对一的关系,一对一的这个关系字段写在两个表的任意一个表里面都可以
  13. class AuthorDetail(models.Model):
  14.         '''
  15.         作者详细信息表
  16.         '''
  17.    
  18.     birthday=models.DateField()
  19.     telephone=models.BigIntegerField()
  20.     addr=models.CharField( max_length=64)
  21. class Publish(models.Model):
  22.     '''
  23.     出版社表
  24.     '''
  25.    
  26.     name=models.CharField( max_length=32)
  27.     city=models.CharField( max_length=32)
  28.     #class Meta:
  29.             #db_table='authordetail'  --指定表名
  30.         #ordering=['id']    --指定排序方式
  31. #多对多的表关系,手动创建一个第三张表,然后写上两个字段,每个字段外键关联到另外两张多对多关系的表,orm的manytomany自动帮我们创建第三张表,两种方式建立关系都可以,手动创建的第三张表进行orm操作的时候,很多关于多对多关系的表之间的orm语句方法无法使用,如果想删除某张表,只需要将这个表注销掉,然后执行那两个数据库同步指令就可以了,自动就删除了。
  32. class Book(models.Model):
  33.     '''
  34.     书籍表
  35.     '''
  36.    
  37.     title = models.CharField( max_length=32)
  38.     publishDate=models.DateField()
  39.     price=models.DecimalField(max_digits=5,decimal_places=2)
  40. publishs=models.ForeignKey(to='Publish',on_delete=models.CASCADE)
  41.         authors=models.ManyToManyFiled('Author',)
  42.     # foreignkey里面可以加很多的参数,to指向表,to_field指向你关联的字段,不写默认会自动关联主键字段,on_delete级联删除 字段名称不需要写成publish_id,orm在翻译foreignkey的时候会自动给你这个字段拼上一个_id,这个字段名称在数据库里面就自动变成了publish_id     
  43.     # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表,并且查看book表的时候,看不到这个字段,因为这个字段就是创建第三张表的意思,不是创建字段的意思,所以只能说这个book类里面有authors这个字段属性
  44.     # 与Publish建立一对多的关系,外键字段建立在多的一方,字段publish如果是外键字段,那么它自动是int类型
  45.      #注意不管是一对多还是多对多,写to这个参数的时候,最后后面的值是个字符串,不然你就需要将你要关联的那个表放到这个表的上面
复制代码
增加

通过两种方式
一对一:
  1. au_obj = models.AuthorDetail.objects.get(id = 4)
  2. models.Author.objects.create(
  3.         name = '韩寒',
  4.         age = 32,
  5.     #方式1:将对象作为值给au,也就是自动将au_obj的id赋值给au_id
  6.         au = au_obj,
  7.    
  8.     #方式2:直接写id值
  9.     #au_id = 4,   
  10.    
  11. )
复制代码
一对多:
  1. pub_obj = models.Publish.objects.get(id = 3)
  2. models.Book.objects.create(
  3.         title = '红楼梦',
  4.         price = 160.00,
  5.         publishDate = '2011-11-12',
  6.     #方式1:类属性作为关键字段时,值为model对象
  7.         publishs = pub_obj,
  8.         #方式2:如果关键字为数据库字段名称,那么值为关联数据的值
  9.         #publish_id = 3
  10.         )
复制代码
多对多:
  1. new_obj = models.Book.objects.create(
  2.         title = '红楼梦',
  3.         price = 180.00,
  4.         publishDate = '2010-08-13',
  5.         publishs_id = 2,
  6.         )
  7. #方式1:
  8. new_obj.authors.add(3,5)   
  9. # new_obj.authors.add(*[3,5])  利用打散的方式,等同于上面的方式
  10. #方式2:
  11. obj1 = models.Author.objects.get(id=3)
  12. obj2 = models.Author.objects.get(id=5)
  13. new_obj.authors.add(obj1,obj2)
复制代码
删除

一对一:
  1. models.AuthorDetail.objects.filter(id=3).delete()
  2. models.Author.objects.filter(id=3).delete()
复制代码
一对多:
  1. models.Publish.objects.filter(id=3).delete()
  2. models.Book.objects.filter(id=4).delete()
复制代码
多对多:
  1. book_obj = models.Book.objects.get(id=2)
  2. book_obj.authors.remove(1)   #指定删除
  3. book_obj.authors.clear()     #清空
  4. book_obj.authors.set(['1','2'])  #先清除在添加,相当于修改
复制代码
修改

修改的方法与添加雷同
  1. ret = models.Publish.objects.get(id=2)
  2. models.Book.objects.filter(id=5).update(
  3.         title = '活着',
  4.     #方式1:
  5.         publishs = ret,
  6.         #方式2:
  7.         #publishs_id = 1,
  8.         )
复制代码
查询

基于对象的跨表查询
一对一查询(Author与AuthorDetail)


  1. 关系属性写在表1,关联到表2,那么通过表1的数据去找表2的数据,叫做正向查询,返过来就是反向查询
  2.    
  3.     # 正向查询  对象.属性
  4.     # 例:查询一下韩寒的电话号码
  5.     obj = models.Author.objects.filter(name='韩寒').first()
  6.     ph = obj.au.telephone
  7.     print(ph)
  8.    
  9.    
  10.     # 反向查询  对象.小写的表名
  11.     # 例:查一下电话号码为120的作者姓名
  12.     obj = models.AuthorDetail.objects.filter(telephone=120).first()
  13.     ret = obj.author.name  
  14.     print(ret)
复制代码
一对多查询(Publish与Book)


  1.     #正向查询
  2.     # 查询一下红楼梦这本书是哪个出版社出版的  
  3.     obj = models.Book.objects.filter(title='海狗的怂逼人生').first()
  4.     ret = obj.publishs.name
  5.     print(ret)  
  6.    
  7.     #反向查询
  8.     # 查询一下 人民出版社出版过哪些书
  9.     obj = models.Publish.objects.filter(name='人民出版社').first()
  10.     ret = obj.book_set.all()
  11.     for i in ret:
  12.         print(i.title)
复制代码
多对多查询(Author与Book)


  1.     # 正向查询
  2.     # 查询一下红楼梦是哪些作者写的
  3.     obj = models.Book.objects.filter(title='海狗的怂逼人生').first()
  4.     ret = obj.authors.all()
  5.     for i in ret:
  6.         print(i.name)
  7.         
  8.     # 反向查询
  9.     # 查询一下韩寒写了哪些书
  10.     obj = models.Author.objects.filter(name='韩寒').first()
  11.     ret = obj.book_set.all()
  12.     for i in ret:
  13.         print(i.title)
  14.         #print(i.publishs.name) --查询这些书的出版社名称
复制代码
3.基于双下划线的跨表查询(基于join实现的)

​ Django还提供了一种直观而且高效的方式在查询(lookups)中表示关联关系,它能自动确认SQL JOIN联系.要做跨关系查询,就利用双下划线来连接模型(model)间关联字段的名称,直到最终连接到必要的model
​ 基于双下划线的查询:正向查询按字段,反向查询按表名小写来告诉orm引擎join哪张表,一对一,一对多,多对多都是一个写法(在写orm查询的时间,哪张表在前哪张表在后都没问题,因为是join连表操纵)
一对一查询

  1. 查询韩寒的手机号
  2. 正向查询
  3. ret = models.Author.objects.filter(name='韩寒').values('au__telephone')
  4. 反向查询
  5. ret = models.AuthorDetail.objects.filter(author__name = '韩寒').values('telephone')
复制代码
一对多查询

  1. 红楼梦是哪个出版社出版的
  2. 正向查询
  3. ret = models.Book.objects.filter(title='红楼梦').values('publishs__name')
  4. 反向查询
  5. ret = models.Publish.objects.filter(book__title='红楼梦').values('name')
  6. 查询一下人民出版社出版了哪些书
  7. 正向查询
  8. ret = models.Book.objects.filter(publishs__name='人民出版社').values('title')
  9. 反向查询
  10. ret = models.Publish.objects.filter(name='人民出版社').values('book_title')
复制代码
多对多查询

  1. 查询一下红楼梦是哪些作者写的
  2. 正向查询
  3. ret = models.Book.objects.filter(title='红楼梦').values('authors__name')
  4. 反向查询
  5. ret = models.Author.objects.filter(book__title='红楼梦').values('name')
复制代码
related_name
反向查询时,如果定义了related_name,则用related_name替换表名,比如
  1. publish = ForeignKey(to='publisher',related_name = 'booklist')
复制代码
  1. 查询人民出版社出版过哪些书
  2. 反向查询 不再按表名:book,而是related_name:booklist
  3. ret = models.Publish.objects.filter(name='人民出版社').values('booklist__title')
复制代码
4.聚合查询和分组查询

聚合查询

aggregate(*args,**kwargs)
  1. 计算所有图书的平均价格
  2. from django.db.models import Avg
  3. ret = models.Book.objects.all().aggregate(Avg('price'))
  4. #或者给它起名字:aggretate(a=Avg('price'))
  5. print(ret)
  6. #{'price__avg':34.35}
复制代码
aggregate()是QuerySet的一个停止语句,意思是说,它返回一个包罗一些键值对的字典.键的名称是聚合值的标识符,值是计算出来的聚合值,键的名称是按照字段和聚合函数的名称自动生成出来的.如果你想为聚合值指定一个名称,可以向聚合子句提供它.
  1. ret = models.Book.objects.aggregate(a=Avg('price'))
  2. print(ret)
  3. #{'a':34.35}
复制代码
如果盼望生成不止一个聚合,可以向aggregate()子句中添加另一个参数,以是,可以如许查询
  1. from django.db.models import Avg,Max,Min,Count
  2. ret = models.Book.objects.aggregate(Avg('price'),Max('price'),Min('price'))
  3. print(ret)
  4. #{'price__avg':34.35,'price__max':Decimal('81.20'),'price__min':Decimal('12.99')}
复制代码
分组查询

annotate()为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)
跨表分组查询的本质就是将关联表join成一张表,再按单表的思路举行分组查询
  1. 查询每个出版社出版的书的平均价格
  2. #用publish表的id字段进行分组
  3. ret = models.Book.objects.values('publish__id').annotate(a=Avg('price'))
  4. #用book表的publish_id字段进行分组
  5. ret = models.Book.objects.values('publishs_id').annotate(a=Avg('price'))
  6. ret = models.Publish.objects.annotate(a=Avg('book__price')).values('a')
复制代码
F查询与Q查询

F查询
假设在book表中加入两个字段:批评数:comment,收藏数:keep
Django提供F()来做如许的比力,F()的实例可以在查询中引用字段,来比力同一个model实例中两个不同字段的值
  1. 查询评论数大于收藏数的书籍
  2. from django.db.models import F
  3. ret = models.Book.objects.filter(comment__gt=F('keep'))
复制代码
Django支持F()对象之间以及F()对象和常数之间的加减乘除和取模的操纵
  1. 查询评论数大于收藏数两倍的书籍
  2. ret = models.Book.objects.filter(comment__gt=F('keep')*2)
复制代码
修改操纵也可以利用F函数,比如将每一本书的价格提高30元
  1. models.Book.objects.all().update(price=F('price')+30)
复制代码
Q查询
filter()等方法中的关键字参数查询都是一起举行'AND'的,如果必要执行更复杂的查询(比方OR语句),可以利用Q对象
Q对象可以利用&(与), |(或) , ~(非) 操纵符组合起来.当一个操纵符在两个Q对象利用时,它产生一个新的Q对象
  1. from django.db.models import Q
  2. ret = models.Book.objects.filter(Q(authors__name='韩寒')|Q(authors__name='余华'))
复制代码
等同于下面的SQL where子句
  1. where name = '韩寒' or name = '余华'
复制代码
可以组合利用& 和 | 操纵符以及利用括号举行分组来编写恣意复杂的Q对象.同时,Q对象可以利用 ~ 操纵符取反,允许组合正常的查询和取反 (not)查询
  1. ret = models.Book.objects.filter(Q(authors__name='韩寒')&~Q(publishdate__year=2017)).values_list('title')
  2. ret = models.Book.objects.filter(Q(Q(authors__name='韩寒')&~Q(publishdate__year=2017))&Q(id__gt=6)).values_list('title')
  3. #可以使用Q嵌套,多层Q嵌套等
复制代码
查询函数可以混合利用Q对象和关键字参数 .全部提供给查询函数的参数(关键字参数或Q对象)都将'AND'在一起,但是,如果出现Q对象,它必须位于全部关键字参数的前面,比方
  1. ret = models.Book.objects.filter(
  2.     Q(publishdate__year=2016) | Q(publishdate__year=2017),
  3.     title='python'   #也是and的关系,但是Q必须写在前面
  4.                                  
  5. )
复制代码
5.ORM执行原生SQL语句

在模型查询API不敷用的情况下,我们还可以利用原始的SQL语句举行查询。
Django 提供两种方法利用原始SQL举行查询:一种是利用raw()方法,举行原始SQL查询并返回模型实例;另一种是完全避开模型层,直接执行自定义的SQL语句。
执行原生查询
raw()管理器方法用于原始的SQL查询,并返回模型的实例:
    注意:raw()语法查询必须包罗主键。
这个方法执行原始的SQL查询,并返回一个django.db.models.query.RawQuerySet 实例。 这个RawQuerySet 实例可以像一般的QuerySet那样,通过迭代来提供对象实例。
举个例子:
  1. class Person(models.Model):
  2.     first_name = models.CharField(...)
  3.     last_name = models.CharField(...)
  4.     birth_date = models.DateField(...)
复制代码
可以像下面如许执行原生sql语句
  1. for p in Person.objects.raw('SELECT * FROM myapp_person'):           print(p)
复制代码
raw()查询可以查询其他表的数据
举例:
  1. ret = models.Student.objects.raw('select id, tname as hehe from app02_teacher')
  2.     for i in ret:
  3.         print(i.id, i.hehe)
复制代码
raw()方法自动将查询字段映射到模型字段。还可以通过translations参数指定一个把查询的字段名和ORM对象实例的字段名互相对应的字典
  1. d = {'tname': 'haha'}
  2.     ret = models.Student.objects.raw('select * from app02_teacher', translations=d)
  3.     for i in ret:
  4.         print(i.id, i.sname, i.haha)
复制代码
原生SQL还可以利用参数,注意不要自己利用字符串格式化拼接SQL语句,防止SQL注入!
  1. d = {'tname': 'haha'}
  2.     ret = models.Student.objects.raw('select * from app02_teacher where id > %s', translations=d, params=[1,])
  3.     for i in ret:
  4.         print(i.id, i.sname, i.haha)
复制代码
直接执行自定义SQL
我们可以直接从django提供的接口中获取数据库连接,然后像利用pymysql模块一样操纵数据库。
  1. from django.db import connection, connections
  2. cursor = connection.cursor()
  3. # cursor = connections['default'].cursor()
  4. cursor.execute("""SELECT * from auth_user where id = %s""", [1])
  5. ret = cursor.fetchone()
复制代码
6.python脚本中调用django环境(django外部脚本利用models)
如果想通过自己创建的python文件在django项目中利用django的models,那么就必要调用django的环境:
  1. import os
  2. if __name__ == '__main__':
  3.     os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
  4.     import django
  5.     django.setup()
  6.     from app01 import models  #引入也要写在上面三句之后
  7.     books = models.Book.objects.all()
  8.     print(books)
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

嚴華

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表