ORM操作单表,逆向输出SQL,一篇长文就get~ __gte__lte注意pycharm链接数据库都需要提前下载对应的驱动,自带的sqlite3对日期格式数据不敏感,如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3
搭建方式
import osif __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day06.settings") import django django.setup()python console
# Mysql配置DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'orm_simple', 'HOST': '127.0.0.1', 'PORT': 3306, 'USER': 'root', 'PASSWORD': 'root', 'CHARSET':'utf8' }}'''__init__.py'''import pymysqlpymysql.install_as_MySQLdb()创建表
from django.db import modelsclass Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=5,decimal_places=2) publish = models.CharField(max_length=32) publish_data = models.DateField() # 出版时间# 路由from django.contrib import adminfrom django.urls import pathfrom app01 import viewsurlpatterns = [ path('admin/', admin.site.urls), path('book/', views.book),]有两种添加数据的方式:
from django.shortcuts import render,HttpResponsefrom app01 import modelsdef book(request): '''添加数据的两种方式''' # 方式1 book_obj = models.Book(title='Python',price='99',publish='Hammer出版社',publish_data='2022-2-2') book_obj.save() # 方式2 models.Book.objects.create(title='Java',price='88',publish='Hans出版社',publish_data='2021-2-1') return HttpResponse('<p>数据添加成功</p>')
all()方法查询所有数据,返回一个QuerySet对象,类似list,可以通过索引来获取列表中的对象,这里不支持负索引
from django.shortcuts import render,HttpResponsefrom app01 import modelsdef book(request): book_obj = models.Book.objects.all() print(book_obj) # <QuerySet [<Book: Book object (1)>, <Book: Book object (2)>]> print(book_obj[0]) # Book object (1) print(book_obj.first()) # Book object (1) 等价于[0] print(book_obj.first().title) # Python 获取值 return HttpResponse('<p>数据查询成功</p>')filter() 方法用于查询符合条件的数据
返回的是 QuerySet 类型数据,类似于 list,里面放的是满足条件的模型类的对象,可用索引下标取出模型类的对象;
def book(request): book_obj = models.Book.objects.filter(pk=2) print(book_obj) print(book_obj.first().title) # JavaScript book_obj1 = models.Book.objects.filter(title='JavaScript',price='99') print(book_obj1.first().pk) # 2 return HttpResponse('<p>数据查询成功</p>')exclude() 方法用于查询不符合条件的数据,返回的是 QuerySet 类型数据,类似于 list,里面放的是不满足条件的模型类的对象,可用索引下标取出模型类的对象;
def book(request): book_obj = models.Book.objects.exclude(pk=2) print(book_obj) # <QuerySet [<Book: Python>, <Book: C>, <Book: PHP>, <Book: C++>, <Book: 数据结构>]> for i in book_obj.all(): print(i.title) # Python C PHP C++ 数据结构 return HttpResponse('<p>数据查询成功</p>')get() 方法用于查询符合条件的返回模型类的对象符合条件的对象只能为一个,如果符合筛选条件的对象超过了一个或者没有一个都会抛出错误
区别filter()如果获取不到符合条件的数据,返回一个空对象,不报错
from django.shortcuts import render,HttpResponsefrom app01 import modelsdef book(request): book_obj = models.Book.objects.get(pk=1) print(book_obj) return HttpResponse('<p>数据查询成功</p>')order_by() 方法用于对查询结果进行排序,返回的是 QuerySet类型数据,类似于list,里面放的是排序后的模型类的对象,可用索引下标取出模型类的对象
def book(request): # 升序排序 book_obj = models.Book.objects.order_by('id') for i in book_obj: print(i.title) # Python JavaScript C PHP C++ 数据结构 # 降序排序 book_obj1 = models.Book.objects.order_by('-id') for i in book_obj1: print(i.title) # 数据结构 C++ PHP C JavaScript Python return HttpResponse('<p>数据查询成功</p>')reverse() 方法用于对查询结果进行反转,返回的是 QuerySe t类型数据,类似于 list,里面放的是反转后的模型类的对象,可用索引下标取出模型类的对象
使用反转函数前先排序
def book(request): # 按照价格升序排列:降序再反转 books = models.Book.objects.order_by("-price").reverse() return HttpResponse("<p>查找成功!</p>")count() 方法用于查询数据的数量返回的数据是整数
def book(request): book_obj = models.Book.objects.count() print(book_obj) # 查询所有数据的数量>>>6 book_obj1 = models.Book.objects.filter(price=200).count() # 查询符合条件数据的数量 return HttpResponse('<p>数据查询成功</p>')exists() 方法用于判断查询的结果 QuerySet 列表里是否有数据,返回的数据类型是布尔,有为 true,没有为 false。
from django.shortcuts import render,HttpResponsefrom app01 import modelsdef book(request): books = models.Book.objects.exists() # True books = models.Book.objects.count().exists() # 报错,判断的数据类型只能为QuerySet类型数据,不能为整型 books = models.Book.objects.first().exists() # 报错,判断的数据类型只能为QuerySet类型数据,不能为模型类对象 return HttpResponse("<p>查找成功!</p>")返回的是 QuerySet 类型数据,类似于 list,里面不是模型类的对象,而是一个可迭代的字典序列,字典里的键是字段,值是数据
def book(request): book_obj = models.Book.objects.values('price','title') print(book_obj) # 返回所有price和title字段,以列表套字典的形式 # <QuerySet [{'price': Decimal('99.00'), 'title': 'Python'}] book_obj1 = models.Book.objects.filter(pk=1).values('title') print(book_obj1,book_obj[0].get('title')) # <QuerySet [{'title': 'Python'}]> Python return HttpResponse('<p>数据查询成功</p>')values_list() 方法用于查询部分字段的数据,values_list() 方法用于查询部分字段的数据
def book(request): book_obj = models.Book.objects.values_list('price','title') print(book_obj) # 返回所有price和title字段,以列表套元组的形式 # <QuerySet [(Decimal('99.00'), 'Python')] for title in book_obj: print(title[1]) # 获取所有title return HttpResponse('<p>数据查询成功</p>')values和values_list区别
distinct() 方法用于对数据进行去重,返回的是 QuerySet 类型数据
注意:
from django.shortcuts import render,HttpResponsefrom app01 import modelsdef book(request): # 查询一共有多少个出版社 books = models.Book.objects.values_list("publish").distinct() # 可以去重 books = models.Book.objects.distinct() # 对模型类的对象去重没有意义,因为每个对象都是一个不一样的存在,主键不一样 return HttpResponse("<p>查找成功!</p>")类似sql的成员运算,用于读取区间,= 号后面为列表
注意:filter 中运算符号只能使用等于号 = ,不能使用大于号 > ,小于号 < ,等等其他符号
def book(request): book_obj = models.Book.objects.filter(price__in=[100,300]) print(book_obj) # <QuerySet [<Book: Book object (2)>, <Book: Book object (22)>]> return HttpResponse('<p>数据查询成功</p>')__gte大于、大于等于
# 价格大于100的数据book_obj = models.Book.objects.filter(price__gt=100)# 价格大于等于100的数据book_obj = models.Book.objects.filter(price__gte=100)__lte小于、小于等于
# 价格小于100的数据book_obj = models.Book.objects.filter(price__lt=100)# 价格小于等于100的数据book_obj = models.Book.objects.filter(price__lte=100)表示范围,在···之间,类似sql的between··and,左闭右区间,= 号后面为两个元素的列表
# 价格在100到200之间的数据book_obj = models.Book.objects.filter(price__range=[100,300])包含关系,=号后面为字符串,类似sql的模糊查询,LIKE
# 查询包含Py字符的书名book_obj = models.Book.objects.filter(title__contains='Py')不区分大小写,和
contains一样
# 查询包含Py字符的书名book_obj = models.Book.objects.filter(title__contains='py')查询以指定字符开头,= 号后面为字符串
book_obj = models.Book.objects.filter(title__startswith='P')查询以指定字符结尾,=号后面为字符串
book_obj = models.Book.objects.filter(title__endswith='构')__year 是 DateField 数据类型的年份,= 号后面为数字
# 2022年出版的数据book_obj = models.Book.objects.filter(publish_date__year=2022)查询月份
# 3月出版的数据book_obj = models.Book.objects.filter(publish_date__month=3)__day 是DateField 数据类型的天数,= 号后面为数字
# 所有17号出版的数据book_obj = models.Book.objects.filter(publish_date__day=17)方式一:使用模型类的 对象.delete()
返回值:元组,第一个元素为受影响的行数
book_obj=models.Book.objects.filter(pk=8).first().delete()方式二:使用 QuerySet 类型数据.delete()(推荐)
返回值:元组,第一个元素为受影响的行数。
books=models.Book.objects.filter(pk__in=[1,2]).delete()注意:
方式一:
模型类的对象.属性 = 更改的属性值模型类的对象.save()def book(request): book_obj = models.Book.objects.filter(pk=23).first() print(book_obj) book_obj.title='如何傍富婆,从入门到入赘' book_obj.save() return HttpResponse('<p>入赘成功</p>')方式二:QuerySet 类型数据.update(字段名=更改的数据)(推荐)
返回值:整数,受影响的行数
def book(request): book_obj = models.Book.objects.filter(pk=23).update(title='人活一口气,打死不入赘') return HttpResponse(book_obj) # 1方式一:
如果想打印orm转换过程中的sql,需要在settings中进行如下配置:
'''settings.py'''LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, }}ps:本质是日志的监控,可以在test下测试
方式二:使用对象.query获取原生SQL()
from app01 import modelsres = models.Book.objects.filter(pk=2)print(res.query)'''SELECT `app01_book`.`id`, `app01_book`.`title`, `app01_book`.`price`, `app01_book`.`publish`, `app01_book`.`publish_date` FROM `app01_book` WHERE `app01_book`.`id` = 2'''