Day49 orm 操作 Django单表操作

1、ORM简介

对象关系映射(Object Relational Mapping,简称ORM)。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。

ORM在业务逻辑层和数据库层之间充当了桥梁的作用。咱们通过一张图来介绍一下数据库与python代码之间的一个关系,请看下图:

ORM的优点:

  • 不用写繁琐的SQL语句,用咱们熟悉的python代码,就能实现对数据的操作,提高开发效率;
  • 可以平滑的操作,切换数据库。

ORM的缺点:

  • ORM代码转换为SQL语句时,需要花费一定的时间,执行效率会有所降低
  • 长期写ORM代码,导致写SQL语句能力,会有所减弱。
  • 如果想打印orm转换过程中的sql,需要在settings中进行如下配置:

只需要把这段代码加载到setting中即可:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}  

 

其实orm就是pycharm中的MySQL语句就行一个桥梁就行内部的访问。

类似于mysql.、Navicat、本地cmd都是客户端去连接远程的mysql服务端,mysql服务端是mysqld。

内部的流程是: python(orm)先转化成SQL语句,然后利用pymysql模块就行和mysql服务端就行相互连接。

2.单表操作

 2.1、Django如何使用MySQL数据库

  •   1创建MySQL数据库。

 注意:ORM无法操作到数据库级别,只能操作到数据表。

如下:在本地数据库中创建一个编码格式为utf8的book_demo 的测试数据库

 create database book_demo default charset=utf8;  # 防止编码问题,指定为utf8.

 

  • 2 settings.py里设置

 1 首先是找到数据库中的

 

 注意:

如果老师让交作业的时候红色框中的数据库是可以不用修改的,他会生成一个文件数据库sqlite3的,不需要配置!!!

## 但是这里 我们需要使用本地的mysql需要配置,配置如下:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '数据库名',
        'HOST': '数据库IP地址',
        'PORT': 3306,
        'USER': 'root',
        'PASSWORD': '',
    }
}

 

  • 3告诉Django使用pymysql模块连接mysql数据库

# 在与settings.py同级目录下的__init__.py中
import pymysql
pymysql.install_as_MySQLdb()

 

  •  4创建模型(在models.py中写类)

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)  # 书籍名称
    price = models.DecimalField(max_digits=5, decimal_places=2)  # 书籍价格
    publisher = models.CharField(max_length=32)  # 出版社名称
    pub_date = models.DateField()  # 出版时间
  • 扩展:更多字段和参数
  • 更多字段:
  • 更多参数:参考陈老师的博客
  • 5执行数据量迁移的命令
python manage.py  makemigrations  # 把models.py的变更记录记录下来
python manage.py  migrate  # 把变更记录的操作同步到数据库中

 

 报错的话:

MySQLclient目前只支持到python3.4,因此如果使用的更高版本的python,需要修改如下:

 需要把上面报错文件中的base,py

if version < (1, 3, 3):

     raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)
 

 

注释掉就可以了。 

 

 

6.查看本次orm关联的数据库day49

不要轻易删除这个表中的文件,以及在Django中相关联的那条记录。默认在数据中创建10张表格。

看看django_migrations 中的和数据库中一一对应的关系是,要删除的话,对应的一起删除 否则会报错!

 

3. 单表操作

3.1添加表记录

  • 方式一:

 通过类实例化对象的方式。注意:一定要对象.save()

book = models.Book(title="吸星大法", price=200, publisher="明教出版社", pub_date="2018-12-12")
book.save()
运行代码:Book object (1), Book object (1) <class 'app01.models.Book'>
  • 方式二:

通过ORM提供的objects提供的方法 create来实现。

book = models.Book.objects.create(title="独孤九剑", price=150, publisher="华山出版社", pub_date="2019-1-12")

 

小结:使用方式2的方法不用手动就行保存。推荐使用。

 

3.2查询表记录

1、查询API

<1> all():                  查询所有结果
def book_list(request):
    # all 查询所有
    books = models.Book.objects.all()  # QuerySet类型 类似于list, 里面是一个个对象
    # 类似于sql: select * from app01_book
    # 查询结果是 <QuerySet [<Book: Book object (1)>,
    # <Book: Book object (2)>, <Book: Book object (3)>,
    # <Book: Book object (4)>, <Book: Book object (5)>,
    # <Book: Book object (6)>, <Book: Book object (7)>,
    # <Book: Book object (8)>, <Book: Book object (9)>,
    # <Book: Book object (10)>, <Book: Book object (11)>,
    # <Book: Book object (12)>, <Book: Book object (13)>,
    # <Book: Book object (14)>]> <class 'django.db.models.query.QuerySet'>
    # 如果在对象的方法中添加魔术属性的对象的时候,可以将打印出来的变成我们想要的东西,这里我们把print(book)用魔术属性打印出其title属性
    #     def __str__(self):
    #         return self.title
    # 1.加上上面的这句话,就会在打印对象的时候生效了!返回你想要的字符串 本次中返回的是对象的title属性
    # 2.可以上边的可以看出models orm模型中每一个实力化对象就是对应中的每一条记录,也就是一个对象==一条记录
    print(books, type(books))
    return HttpResponse('查询成功!')

 

<2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象
 # filter 过滤
    books = models.Book.objects.filter(pk=3)  # QuerySet 类似于list, 满足条件的对象集
    # 1.filter相当于 select * from app01_book where pk=3
    # 2.<QuerySet [<Book: 易经2>]> <class 'django.db.models.query.QuerySet'>
 
  
<3> get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
                            如果符合筛选条件的对象超过一个或者没有都会抛出错误。
# get 获取一个对象
    # 直接获取出对象  注意: 当查询条件不存在或者查询出结果有多个值时,会报错。
    # 存在
    books = models.Book.objects.get(pk=4)
    # 易经筋 <class 'app01.models.Book'>,打印出来的易经筋本来是打印出的对象,由于魔术方法str导致的,记得!!
    # 不存在 都是直接获取出对象
    # books = models.Book.objects.get(pk=18)
    # app01.models.Book.DoesNotExist: Book matching query does not exist.
    # 都是直接获取出对象,获取有多个对象的时候会报错!
    # books = models.Book.objects.get(price=200)
 
  
<4> exclude(**kwargs):      它包含了与所给筛选条件不匹配的对象,是QuerySet 类似于list, 满足条件的对象集
 
 # exclude 获取不满足的条件的 对象的集合
    # 类似于not 排除满足条件的对象。剩下的取出来即可。
    books = models.Book.objects.exclude(publish='少林出版社', price=200)
    print(books, type(books))
    # <QuerySet [<Book: 易经>, <Book: 易经>, <Book: 易经2>, 
    # <Book: 易经筋>, <Book: 易经筋>, <Book: 独孤九剑>, 
    # <Book: 挤奶龙爪手>, <Book: 冲灵剑法>, <Book: 吸星大法>, 
    # <Book: 葵花宝典>, <Book: 乾坤大挪移>, <Book: 九阴真经>,
    # <Book: 九阳神功>, 
    # <Book: 九阴白骨爪>]> <class 'django.db.models.query.QuerySet'>
<5> order_by(*field):       对查询结果排序,容易的看出下面的确实相反的操作 一个升序 一个降序,都是对象多条表记录对象就行操作
 # order by("price")默认是升序
    # order by("-price") 按照价格就行倒序排 排的也是
    books = models.Book.objects.order_by("price")
    # <QuerySet [<Book: 九阴白骨爪>, <Book: 易经筋>,
    # <Book: 易经筋>, <Book: 冲灵剑法>, <Book: 独孤九剑>,
    # <Book: 吸星大法>, <Book: 易经>, <Book: 易经>, <Book: 易经2>, 
    # <Book: 挤奶龙爪手>, <Book: 九阴真经>, <Book: 九阳神功>, 
    # <Book: 乾坤大挪移>, <Book: 葵花宝典>]> 
    # <class 'django.db.models.query.QuerySet'>
    print(books, type(books))
    books = models.Book.objects.order_by("-price")
    print(books, type(books))
    # <QuerySet [<Book: 葵花宝典>, <Book: 乾坤大挪移>,
    # <Book: 九阳神功>, <Book: 九阴真经>, <Book: 易经>,
    # <Book: 易经>, <Book: 易经2>, <Book: 挤奶龙爪手>,
    # <Book: 吸星大法>, <Book: 独孤九剑>, <Book: 冲灵剑法>,
    # <Book: 易经筋>, <Book: 易经筋>, <Book: 九阴白骨爪>]> 
    # <class 'django.db.models.query.QuerySet'>
 
  
<6> reverse(): 对查询结果反向排序,可以看出,第一按照price就行查询结果的升序排列,然后再使用reverse就行降序排列,感觉很累赘,感觉完全使用oder_by("-price")同第5个就搞定了啊
 # reverse 默认是将查询结果就行返序列 默认是降序
    books = models.Book.objects.order_by("price").reverse()
    # <QuerySet [<Book: 葵花宝典>, <Book: 乾坤大挪移>,
    # <Book: 九阳神功>, <Book: 九阴真经>, <Book: 易经>,
    # <Book: 易经>, <Book: 易经2>, <Book: 挤奶龙爪手>, 
    # <Book: 吸星大法>, <Book: 独孤九剑>, <Book: 冲灵剑法>,
    # <Book: 易经筋>, <Book: 易经筋>, <Book: 九阴白骨爪>]> 
    # <class 'django.db.models.query.QuerySet'>
    print(books, type(books))
 
  
<7> count():   返回数据库中匹配查询(QuerySet)的对象数量。
    # count # 14 <class 'int'>
    books = models.Book.objects.all().count()
    print(books, type(books))
    # exists  False <class 'bool'>
    books = models.Book.objects.filter(pk=18).exists()  # 返回值为布尔值
    print(books, type(books))
    return HttpResponse('查询成功!')
 
  

 

<8> first():    返回第一条记录
  
<9> last():    返回最后一条记录
# first 与 last() 一般都要集合query对象结合使用,也就是说包含对象的集合使用。比如filter 返回的是一个query对象集合,

    # 从结果可以看出对象集合中只有一个对象  只要是对象集合就可以使用first() 什么last类似于索引讲具体的对象取出来
    # books = models.Book.objects.filter(pk=4)  # 得到query对象集合
    # <QuerySet [<Book: 易经筋>]> <class 'django.db.models.query.QuerySet'>
    # 取出集合中的第一个的元素对象
    books = models.Book.objects.filter(pk=4).first()
    print(books, type(books))
    # 易经筋 <class 'app01.models.Book'>
    # 取出集合中的最后一个元素对象
    # books = models.Book.objects.filter(pk=4).last()  # 类似于get直接将对象取出来,
    # 易经筋 <class 'app01.models.Book'>
    print(books, type(books))
注意:由于在 filter筛选的时候得到的集合时1个对象,即是第一个对象和最后一个对象都是一样的 哈哈!!
 
  
<10> exists():              如果QuerySet包含数据,就返回True,否则返回False
 
<11> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
                            model的实例化对象,而是一个可迭代的字典序列,其中'title'和'price'对应的值就是数据库中的值!,整个返回的整体是一个Query对象
 # values()
    books = models.Book.objects.filter(price=200).values('title', 'price')
    print(books, type(books))
    # <QuerySet [
    # {'title': '易经', 'price': Decimal('200.00')}, 
    # {'title': '易经', 'price': Decimal('200.00')}, 
    # {'title': '易经2', 'price': Decimal('200.00')},
    # {'title': '挤奶龙爪手', 'price': Decimal('200.00')}
    # ]>
    # <class 'django.db.models.query.QuerySet'>
<12> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
 # values_list
    books = models.Book.objects.filter(price=200).values_list('title', 'price')
    print(books, type(books))
    # <QuerySet [
    # ('易经', Decimal('200.00')), 
    # ('易经', Decimal('200.00')), 
    # ('易经2', Decimal('200.00')),
    # ('挤奶龙爪手', Decimal('200.00'))
    # ]> 
    # <class 'django.db.models.query.QuerySet'> 
 
  
<13> distinct():            从返回结果中剔除重复纪录
 # distinct()
    books = models.Book.objects.filter(price=200).values()
    print(books, type(books))
    # <QuerySet [
    # {'id': 1, 'title': '易经', 'price': Decimal('200.00'), 'publish': '人民出版社', 'pub_date': datetime.date(2009, 12, 12)}, 
    # {'id': 2, 'title': '易经', 'price': Decimal('200.00'), 'publish': '人民出版社', 'pub_date': datetime.date(2009, 12, 12)}, 
    # {'id': 3, 'title': '易经2', 'price': Decimal('200.00'), 'publish': '人民出版社', 'pub_date': datetime.date(2009, 12,12)}, 
    # {'id': 7, 'title': '挤奶龙爪手', 'price': Decimal('200.00'), 'publish': '华山出版社', 'pub_date': datetime.date(2019, 2,22)}
    # ]>
    # <class 'django.db.models.query.QuerySet'>

books = models.Book.objects.filter(price=200).values_list("price")
# <QuerySet [(Decimal('200.00'),), (Decimal('200.00'),)]> <class 'django.db.models.query.QuerySet'>
# books = models.Book.objects.filter(price=200).values_list("price").distinct()
# <QuerySet [(Decimal('200.00'),)]> <class 'django.db.models.query.QuerySet'>

 

 

3.3、基于双下划线的模糊查询 

Book.objects.filter(price__in=[100,200,300])
Book.objects.filter(price__gt=100)
Book.objects.filter(price__lt=100)
Book.objects.filter(price__range=[100,200])
Book.objects.filter(title__contains="")
Book.objects.filter(title__icontains="python")  # 不区分大小写
Book.objects.filter(title__startswith="")
Book.objects.filter(pub_date__year=2018)
   # 基于双下划线的模糊查询
    books = models.Book.objects.filter(price__range=[100, 200])# filter里面都是放的一个一个的对象
  print(books, type(books))
    # <QuerySet [
    # <Book: 易经>, <Book: 易经>, <Book: 易经2>, <Book: 易经筋>, 
    # <Book: 易经筋>, <Book: 独孤九剑>, <Book: 挤奶龙爪手>,
    # <Book: 冲灵剑法>, <Book: 吸星大法>
    # ]> 
    # <class 'django.db.models.query.QuerySet'>
    books = models.Book.objects.filter(title__contains="")
    print(books, type(books))
    # <QuerySet [<Book: 冲灵剑法>, <Book: 吸星大法>]> <class 'django.db.models.query.QuerySet'>
    books = models.Book.objects.filter(title__startswith="")
    print(books, type(books))
    # <QuerySet [<Book: 九阴真经>, <Book: 九阳神功>, <Book: 九阴白骨爪>]> <class 'django.db.models.query.QuerySet'>
    books = models.Book.objects.filter(pub_date__year=2018)
    print(books, type(books))
    # <QuerySet [<Book: 葵花宝典>]> <class 'django.db.models.query.QuerySet'>

 

 

 3.4.删除表记录

def del_book(request):
    pk = request.GET.get("pk")
    print(pk)
    # 方式一 调用QuerySet的delete方法
    # books = models.Book.objects.filter(pk=pk).delete()


    # 方式二 obj.delete()
    # books = models.Book.objects.get(pk=pk)  # 当用户输入pk不存在时,还会报错,pass掉
    books = models.Book.objects.filter(pk=pk).first()
    books.delete()
    print(books)

    return HttpResponse("删除成功!")
def del_book(request):
    pk = request.GET.get("pk")
    print(pk)
    # 方式一 调用QuerySet的delete方法
    books = models.Book.objects.filter(pk=pk).delete()
    # 1,删除该条的时候如果存在直接返回
    # 返回值是:(1, {'app01.Book': 1})
    # 2.如果删除的时候该条记录不存在那么返回一个空的
    # 方式二 obj.delete()
    # (0, {'app01.Book': 0}返回的意思是 在app01_book 中受影响的行数是0行,即是删除的数据不存在也不会报错!
    # books = models.Book.objects.get(pk=pk)  # 当用户输入pk不存在时,还会报错,pass掉
    # books = models.Book.objects.filter(pk=pk).first()
    # books.delete()
    print(books)

    return HttpResponse("删除成功!")

 

 

3.5、修改表记录
def edit_book(request):
    pk = request.GET.get("pk")
    # 方式一: 调用QuerySet的update方法
    # books = models.Book.objects.filter(pk=pk).update(price=280)

    # 方式二: obj更改属性值, 必须要save()同步到数据库。
    books = models.Book.objects.filter(pk=pk).first()
    books.price = 189
    books.save()

    print(books)

    return HttpResponse("编辑成功!")
def edit_book(request):
    pk = request.GET.get("pk")
    # 方式一: 调用QuerySet的update方法
    books = models.Book.objects.filter(pk=pk).update(price=280)
    print(books)  # 1 更新条数
    # 方式二: obj更改属性值, 必须要save()同步到数据库。
    # books = models.Book.objects.filter(pk=pk).first()
    # books.price = 189
    # books.save()
            
    # print(books) #挤奶龙爪手 是一个对象 只是魔术方法使打印对象变成了一个自己想打印的东西 这里打印的是对象的title属性

    return HttpResponse("编辑成功!")

 

 

转载于:https://www.cnblogs.com/longerandergou/p/11144447.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值