Django框架学习_day06

继续数据的查询

filter(属性名1=值1,属性名2=值2)
语法:Mymodel.objects.filter(…)
作用:指定关键字的值来查询数据,返回的是一个QuerySet,存放的object实例
括号中可以传递多个查询参数,用逗号隔开,相当于 “与” 的操作。

这里对Book类中的__str__函数进行了定义,这样显示的更加清楚

    def __str__(self):
        return "书名为:{},出版社为:{},价格为:{},单价为:{}".format(self.title, self.pub, self.price, self.mark_price)
In [1]: from bookstore.models import Book

In [2]: b1 = Book.objects.filter(title='Python')

In [3]: b1
Out[3]: <QuerySet [<Book: 书名为:Python,出版社为:清华大学出版社,价格为:20.00,单价为:25.00>]>

In [8]: Book.objects.filter(pub='清华大学出版社')
Out[8]: <QuerySet [<Book: 书名为:Python,出版社为:清华大学出版社,价格为:20.00,单价为:25.00>, <Book: 书名为:Django,出版社为:清华大学出版社,价格为:70.00,单价为:75.00>, <Book:
书名为:HTML5,出版社为:清华大学出版社,价格为:90.00,单价为:105.00>]>

In [9]: Book.objects.filter(pub='清华大学出版社',title='Django')
Out[9]: <QuerySet [<Book: 书名为:Django,出版社为:清华大学出版社,价格为:70.00,单价为:75.00>]>

In [11]: b1 = Book.objects.filter(pub='清华大学出版社',title='Django')

In [12]: print(b1.query)# 这个方法可以显示在Mysql中对该数据进行查询的代码段
SELECT `book`.`id`, `book`.`title`, `book`.`pub`, `book`.`price`, `book`.`mark_price` FROM `book` WHERE (`book`.`pub` = 清华大学出版社 AND `book`.`title` = Django)

exclude(条件)
语法:MyModel.objects.exclude(条件)
作用:返回除这个条件以外的所有数据
返回值:QuerySet对象,内容为Model对象

In [16]: Book.objects.exclude(pub='清华大学出版社',price=20.00)# 除了清华大学出版社,且价格为20.00的数据,其他所有的都输出
Out[16]: <QuerySet [<Book: 书名为:Java,出版社为:电子科技大学出版社,价格为:25.00,单价为:30.00>, <Book: 书名为:Django,出版社为:清华大学出版社,价格为:70.00,单价为:75.00>, <Boo
k: 书名为:JQure,出版社为:机械工业出版社,价格为:90.00,单价为:85.00>, <Book: 书名为:Linux,出版社为:机械工业出版社,价格为:80.00,单价为:65.00>, <Book: 书名为:HTML5,出版社为:
清华大学出版社,价格为:90.00,单价为:105.00>]>

get(条件)
语法:MyModel.objects.get(条件)
作用:返回一条数据,有且仅有一条,如果查询多与一天,或者不含有该条件的数据,就会抛出异常
返回值:model对象

In [18]: Book.objects.get(title='Python')
Out[18]: <Book: 书名为:Python,出版社为:清华大学出版社,价格为:20.00,单价为:25.00>

查询谓词
做灵活的查询操作的时候需要用到查询谓词,比如大小于等
每一个查询谓词都是一个独立的查询功能

__exact:等值匹配

Book.objects.filter(id__exact=1) # 表示查询id值为1的数据


__contains:包含匹配

Book.objects.filter(title__contain=‘a’)# 查询title中含有’a’的数据


__startswith: 以xxx开始
__endswith: 以xxx结束

Book.object.filter(title__startswith=‘py’)# 查询以py开头的title数据
Book.object.filter(title__startswith=‘on’)# 查询以on结尾的title数据


__gt:大于
__gte:大于等于
__lt:小于
__lte:小于等于

Book.objects.filter(id_gt=1) # 返回id大于1的数据
Book.objects.filter(id_gte=1) # 返回id大于等于1的数据
Book.objects.filter(id_lt=1) # 返回id小于1的数据
Book.objects.filter(id_lte=1) # 返回id小于等于1的数据


__in:查询是否在一个列表中
__range:在指定范围的数据

Book.objects.filter(title_in=[‘Python’,‘Java’]) # 查询在这个列表中的数据
Book.objects.filter(id_range=(1,5)) # 查询在1到5之间的数据


更多查询谓词https://docs.djangoproject.com/en/2.2/ref/models/querysets/#field-lookups


更新操作
更新单个数据

  1. 查询—get()方法
  2. 修改—对象.属性=值
  3. 保存—对象.save()
In [21]: b1 = Book.objects.get(title='Python')

In [22]: b1.price = 1000

In [23]: b1.save()

In [24]: b1
Out[24]: <Book: 书名为:Python,出版社为:清华大学出版社,价格为:1000,单价为:25.00>

Django框架学习_day06

批量更新数据

  1. 先返回一个QuerySet值
  2. 直接调用QuerySet的update(属性=值)的操作
book1 = Book.objects.filter(id__gt=1)
book1.update(price=0)

完善bookstore/all_book/这个网页中的更新的操作
Django框架学习_day06
要求:
点击更新跳转到一个新的页面,对该行数据进行更改
只允许更改pricemarker_price的值

  1. 首先要思考没一行中更新的url如何设置,可以添加筛选器的方式
<a href="/bookstore/update/{{ book.id }}">更新</a>
  1. 创建一个更新的主路由update
    path('update/<int:book_id>',views.update)

  2. 在views中实现函数

def update(requests, book_id):
    try:# 根据id获取book对象
        book = Book.objects.get(id=book_id)
    except Exception as e:
        print('--update book error is %s' % e)
        return HttpResponse('ERROR')

    if requests.method == "GET":# 请求为GET时,返回一个新的修改页面,即为点击更新时
        return render(requests, 'update.html', locals())

    elif requests.method == "POST":# 请求为POST时,对数据库中的数据进行更新,返回主页面,即为点击提交时
        price = requests.POST['price']
        market_price = requests.POST['market_price']
        book.price = price
        book.market_price = market_price
        book.save()
        print(1)
        return HttpResponseRedirect('/bookstore/all_book')
  1. 在templates中创建更新的界面模板
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/bookstore/update/{{ book.id }}" method="POST">
<!--  创建一个表单属性,向/bookstore/update/{{ book.id }}发送数据,类型为POST型-->
  <p>
    title<input type="text" disabled="disabled" name="title" value="{{ book.title }}">
<!--    title为不可更改的属性,设置disabled为disabled-->
  </p>
  <p>
    pub<input type="text" disabled="disabled" name="pub" value="{{ book.pub }}">
  </p>
  <p>
    price<input type="number" name="price" value="{{ book.price }}" max="200">
<!--    price为可更改的属性,但是有取值范围,所以设置其值要在200以内-->
  </p>
  <p>
    market_price<input type="number" name="market_price" value="{{ book.mark_price }}" max="200">
  </p>
  <p>
    <input type="submit" value="提交">
<!--    最后添加一个提交按钮-->
  </p>

</form>
</body>
</html>
  1. 然后就可以点击更新进行数据的更新了
    数据的删除
    单个数据的删除

首先要获取到QuerySet对象
然后执行对象.delete()的方法就可以删除了

In [1]: from bookstore.models import Book

In [2]: b1 = Book.objects.get(id=2)

In [3]: b1
Out[3]: <Book: 书名为:Java,出版社为:电子科技大学出版社,价格为:25.00,单价为:30.00>

In [4]: b1.delete()
Out[4]: (1, {'bookstore.Book': 1})

Django框架学习_day06
伪删除

不会把数据库中的对象真的删除,在表中添加一个新的bool属性is_active(默认为True),执行伪删除时,将is_active字段设置为False,就可以了


注意:使用伪删除的时候,确保显示数据的地方均加了`is_active=True`的过滤查询

完善删除操作

  1. 在Book类中添加一个BooleanField()属性,默认为True,并更新到数据库中
  2. 在views中创建一个新的函数
def delete(requests):

    book_id = requests.GET['book_id']
    try:
        book = Book.objects.get(id=book_id)
    except Exception as e:
        print('Delete error is %s ' % e)
        return HttpResponse("ERROR")
    if requests.method == "GET":
	    book.is_active = False
	    book.save()# 修改了数据,就一定要保存一下
	    return HttpResponseRedirect('/bookstore/all_book')# 返回主页面
  1. 创建一个新路由
    path('delete',views.delete)
  1. 修改主页面的html文件,将删除的a标签的href加上
<a href="/bookstore/delete?book_id={{ book.id }}">删除</a>

然后就可以进行删除数据了


django中的F对象

一个F对象表述数据库中某条记录 字段信息
语法:

from django.db.models import F
F(‘列’)

作用:

通常是在数据库的值在不获取的情况下进行操作
用于类属性(字段)之间的比较

例:
Book.objects.update(price=F(‘price’)+1)
这个代码是将说有书籍的price在原来的基础上加一,这个可以处理高并发的事件,
注意和

for i in Book.object.all() :
i.price = i.price+1
i.save()

的比较,F是不用得到原来的数据,只是自增的一个操作,而下面的是还要取得原来的数据再将其进行加和操作

In [6]: Book.objects.all()
Out[6]: <QuerySet [<Book: 书名为:Python,出版社为:清华大学出版社,价格为:150.00,单价为:200.00>, <Book: 书名为:Django,出版社为:清华大学出版社,价格为:70.00,单价为:75.00>, <Book
: 书名为:JQure,出版社为:机械工业出版社,价格为:90.00,单价为:85.00>, <Book: 书名为:Linux,出版社为:机械工业出版社,价格为:80.00,单价为:65.00>, <Book: 书名为:HTML5,出版社为:清
华大学出版社,价格为:90.00,单价为:105.00>]>

In [7]: Book.objects.update(price=F('price')+1)
Out[7]: 5

In [8]: Book.objects.all()
Out[8]: <QuerySet [<Book: 书名为:Python,出版社为:清华大学出版社,价格为:151.00,单价为:200.00>, <Book: 书名为:Django,出版社为:清华大学出版社,价格为:71.00,单价为:75.00>, <Book
: 书名为:JQure,出版社为:机械工业出版社,价格为:91.00,单价为:85.00>, <Book: 书名为:Linux,出版社为:机械工业出版社,价格为:81.00,单价为:65.00>, <Book: 书名为:HTML5,出版社为:清
华大学出版社,价格为:91.00,单价为:105.00>]>


Q对象

实现逻辑或|,逻辑非~
语法:

from django.db.models import Q
Q(条件1)|Q(条件2) 这就是逻辑或
Q(条件1)&~Q(条件2) 逻辑与非,条件1成立且条件2不成立


Book.objects.filter(Q(price__lt=10)|Q(title__in=[‘Python’,‘Django’]))
取价格小于10的数据,或者书名为Python或Django的数据

In [4]: Book.objects.filter(Q(price__lt=10)|Q(title__in=['Python','Django']))
Out[4]: <QuerySet [<Book: 书名为:Python,出版社为:清华大学出版社,价格为:150.00,单价为:200.00>, <Book: 书名为:Django,出版社为:清华大学出版社,价格为:70.00,单价为:75.00>]>

上一篇:RHCE_DAY06


下一篇:day06