• pt25django教程


    查询数据

    通过 MyModel.objects 管理器方法调用查询接口,查询数据库

    方法说明
    all()查询全部记录,返回QuerySet查询对象
    get()查询符合条件的单一记录
    filter()查询符合条件的多条记录
    exclude()查询符合条件之外的全部记录
    all()方法

    MyModel.objects.all()

    查询MyModel实体中所有的数据,等同于 select * from tabel;
    返回值: QuerySet容器对象,内部存放 MyModel 实例

    from bookstore.models import Book
    books = Book.objects.all()
    for book in books:
        print("书名", book.title, '出版社:', book.pub)
        
    [root@vm mysite2]# python3 manage.py shell
    >>> from bookstore.models import Book
    >>> books = Book.objects.all()
    >>> for book in books:
    ...     print("书名:", book.title, '价格:', book.price,'出版社:', book.pub)
    ...
    书名: java 价格: 50.00 出版社:
    
    >>> for book in books:
    ...     print(book)
    ...
    Book object (1)
    Book object (2)
                
    
    #数据库信息    
    +----+-------+-------+--------------+-----+
    | id | title | price | market_price | pub |
    +----+-------+-------+--------------+-----+
    |  1 | java  | 50.00 |         0.00 |     |
    +----+-------+-------+--------------+-----+
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    返回自定义字符串

    在模型类中重写__str__ 方法,实现自定义默认的字符串

    [root@vm mysite2]# vim bookstore/models.py
    
    class Book(models.Model):
        title = ...
        def __str__(self):
            info = "书名: %s, 出版社: %s, 定价: %s" % (self.title, self.pub, self.price)
            return info
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    #重新登录终端
    [root@vm mysite2]# python3 manage.py shell
    >>> from bookstore.models import Book
    >>> books = Book.objects.all()
    >>> for book in books:
    ...     print(book)
    ...
    书名: java, 出版社: , 定价: 50.00
    书名: python, 出版社: 清华, 定价: 50.00
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    查询返回指定列(字典表示)

    用法: MyModel.objects.values(列1,列2…)

    • 作用: 查询部分列的数据并返回,同select 列1,列2 from xxx

    • 返回值: QuerySet,返回查询结果容器,容器内存字典,每个字典代表一条数据,格式为: {‘列1’: 值1, ‘列2’: 值2}

    from bookstore.models import Book
    books = Book.objects.values("title", "pub")
    for book in books:
        print("书名", book["title"], '出版社:', book['pub'])
        print("book=", book)
        
    #打印    
    书名 java 出版社:
    book= {'title': 'java', 'pub': ''}  
    书名 python 出版社: 清华
    book= {'title': 'python', 'pub': '清华'}
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    查询返回指定列(元组表示)

    用法:MyModel.objects.values_list(列1,列2…)

    • 作用::返回元组形式的查询结果,返回值: QuerySet容器对象,内部存放元组

      会将查询出来的数据封装到元组中,再封装到查询集合QuerySet中

    from bookstore.models import Book
    books = Book.objects.values_list("title", "pub")
    for book in books:
        print("书名", book[0], '出版社:', book[1])
        print("book=", book)
        
    #打印    
    书名 java 出版社:
    book= ('java', '')
    书名 python 出版社: 清华
    book= ('python', '清华')... 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    排序查询 order_by
    • 方法:order_by,用法:MyModel.objects.order_by(‘-列’,‘列’)
    • 作用: 用SQL 语句的ORDER BY对查询结果,根据某个字段选择性的进行排序。默认是按照升序排序,降序排序则需要在列前增加’-'表示
    from bookstore.models import Book
    books = Book.objects.order_by("-price")
    for book in books:
        print("书名:", book.title, '定价:', book.price)
        
    书名: xiyou 定价: 700.00
    书名: c++ 定价: 100.00
    书名: honglou 定价: 90.00    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    条件查询 - filter
    • 方法: filter(条件),语法: MyModel.objects.filter(属性1=值1, 属性2=值2)

    • 返回值:QuerySet容器对象,内部存放 MyModel 实例

    • 说明: 当多个属性在一起时为"与"关系,

    # 查询书中出版社为"清华大学出版社"的图书
    from bookstore.models import Book
    books = Book.objects.filter(pub="清华",price=100)
    for book in books:
        print("书名:", book.title)
        
    书名: c++
        
    
    # 查询Author实体中name为王老师并且age是28岁的
        authors=Author.objects.filter(name='王老师',age=28)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    条件查询 - get
    • 方法: get(条件) 语法: MyModel.objects.get(条件)

    • 作用:返回满足条件的唯一一条数据,编码时,一定要加try。

    • 说明: 该方法只能返回一条数据

      - 查询结果多余一条数据则抛出,Model.MultipleObjectsReturned异常
      - 查询结果如果没有数据则抛出Model.DoesNotExist异常
      
      • 1
      • 2

    使用:

    >>> from bookstore.models import Book
    >>> book = Book.objects.get(id=1)
    >>> print(book)
    书名: java, 出版社: , 定价: 50.00
    >>> print(book.title)
    java
    
    #报错
    >>> book = Book.objects.get(id=9)
    ...
    bookstore.models.Book.DoesNotExist: Book matching query does not exist.
    
    >>> book = Book.objects.get(pub="清华")
    ...
    bookstore.models.Book.MultipleObjectsReturned: get() returned more than one Book -- it returned 2!
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    对比filter和get方法

    filter()方法:返回的是QuerySet类型,可以有0个、1个、多个对象。
    get()方法:返回的是一个模型类的对象,只能返回1个对象,0个或多个将会报错!
    	      所以对于get方法,编码时,一定要加try。      
    
    • 1
    • 2
    • 3
    条件查询 - exclude
    • 方法: exclude(条件) 语法: MyModel.objects.exclude(条件)
    • 作用:,返回不包含此 条件的 全部的数据集
    #查询 清华  出版社,定价等于50以外的全部图书
    >>> books = Book.objects.exclude(pub="清华", price=50)
    >>> for book in books:
    ...     print(book)
    
    • 1
    • 2
    • 3
    • 4
    使用orm做数据的查询注意:
        MyModel.objects.all();
        MyModel.objects.values();
        MyModel.objects.values_list();
        MyModel.objects.get(); 
        MyModel.objects.filter();
        MyModel.objects.exclude(); 
        MyModel.objects.order_by();
        只有get返回单个对象,其他返回的是QuerySet容器。
        values返回的容器中的元素是字典;values_list则是元组;其他都是对象	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    查询谓词

    每一个查询谓词是一个独立的查询功能

    __exact : 等值匹配
    Author.objects.filter(id__exact=1)  #等同id=1
    # 等同于select * from author where id = 1
    
    • 1
    • 2
    __contains : 包含指定值
    Author.objects.filter(name__contains='w')
    # 等同于 select * from author where name like '%w%'
    
    • 1
    • 2
    __startswith : 以 XXX 开始
    __endswith : 以 XXX 结束
    __gt : 大于指定值
    Author.objects.filer(age__gt=50)
    # 等同于 select * from author where age > 50
    
    __lt : 小于
    __gte : 大于等于
    __lte : 小于等于
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    __in : 指定范围内
    Author.objects.filter(country__in=['中国','日本','韩国'])
    # 等同于 select * from author where country in ('中国','日本','韩国')
    
    • 1
    • 2
    __range : 指定的区间范围内
    # 查找年龄在某一区间内的所有作者,包含边界值
    Author.objects.filter(age__range=(35,50))
    # 等同于 SELECT ... WHERE Author BETWEEN 35 and 50;
    
    • 1
    • 2
    • 3

    详细内容参见: https://docs.djangoproject.com/en/2.2/ref/models/querysets/#field-lookups

    修改数据

    修改单个实体的某些字段值的步骤:
    1. 查,通过 get() 得到要修改的实体对象
    2. 改,通过 对象.属性 的方式修改数据
    3. 存,通过 对象.save() 保存数据
    >>> from bookstore.models import Book
    >>> abook = Book.objects.get(id=1)
    >>> print(abook.price)
    50.00
    >>> abook.price = "10.5"
    >>> abook.save()
    >>> print(abook.price)
    10.5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    通过 QuerySet 批量修改 对应的全部字段

    直接调用QuerySet的update(属性=值) 实现批量修改 ,也可批量改一条

    返回值:更新数据的数量

    # 将id大于3的所有图书价格定为0元
    books = Book.objects.filter(id__gt=3)
    books.update(price=0)
    
    # 将所有书的零售价定为100元
    books = Book.objects.all()
    books.update(market_price=100)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    删除数据

    • 删除记录是指删除数据库中的一条或多条记录
    • 删除单个MyModel对象或删除一个查询结果集(QuerySet)中的全部对象都是调用 delete()方法
    删除单个对象
    1. 查找查询结果对应的一个数据对象
    2. 调用这个数据对象的delete()方法实现删除
    try:
        auth = Author.objects.get(id=1)
        auth.delete()
    except:
        print(删除失败)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    删除查询结果集
    1. 查找查询结果集中满足条件的全部QuerySet查询集合对象,
    2. 调用查询集合对象的delete()方法实现删除,生成一条sql执行
    # 删除全部作者中,年龄大于65的全部信息
    auths = Author.objects.filter(age__gt=65)
    auths.delete()
    
    • 1
    • 2
    • 3

    图书管理系统搭建

    (结合页面完成增删改查)

    查询功能
              url:    http://127.0.0.1:8000/bookstore/books
              view: views.books_view 
              html:  "bookstore/books.html"
              models: Book类
              
    添加功能
              url:    http://127.0.0.1:8000/bookstore/add_book
              view: views.add_book 
              html:  "bookstore/add_book.html"
              models: Book类
    预览:
    
    添加图书
    ID	书名	出版社	定价	零售价	操作
    1	java		10.50	0.00	修改 删除
    ...
    
    
    [root@vm ~]# mysql -uroot -p123456 -e "select * from mysite2.bookstore_book"
    +----+---------+--------+--------------+--------+
    | id | title   | price  | market_price | pub    |
    +----+---------+--------+--------------+--------+
    |  1 | java    |  50.00 |         0.00 |        |
    |  2 | python  |  50.00 |         0.00 | 清华   |
    |  3 | c++     | 100.00 |         0.00 | 清华   |
    |  4 | xiyou   | 700.00 |         0.00 | beida  |
    |  5 | honglou |  90.00 |         0.00 | beida  |
    +----+---------+--------+--------------+--------+
              
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    回顾下之前创建好的配置

    [root@vm mysite2]# python3 manage.py startapp bookstore
    [root@vm mysite2]# vim mysite2/settings.py
    
    INSTALLED_APPS = [
    ...
        'bookstore',
    
    [root@vm mysite2]# vim bookstore/models.py
    
    class Book(models.Model):
        title = models.CharField("书名", max_length=50, default='')
        price = models.DecimalField('定价', max_digits=7, decimal_places=2, default=0.0)
    
        # 新增属性/字段 (要有默认值)
        market_price = models.DecimalField("零售价",max_digits=5,decimal_places=2,default=0.0)
    
        pub = models.CharField("出版社", max_length=50,default="")
    
        def __str__(self):
            info = "书名: %s, 出版社: %s, 定价: %s" % (self.title, self.pub, self.price)
            return info
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    新增bookstore/books.html配置
    [root@vm mysite2]# vim bookstore/urls.py
    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('books',views.books_view),
    ]
    
    
    [root@vm mysite2]# vim bookstore/views.py
    from django.shortcuts import render
    from django.http import HttpResponse, HttpResponseRedirect
    from .models import Book
    
    # Create your views here.
    def add_book(request):
        books = Book.objects.all()
        return render(request,
                      'bookstore/books.html',
                      locals())
    
    
    [root@vm mysite2]# mkdir -p bookstore/templates/bootstore
    [root@vm mysite2]# vim bookstore/templates/bootstore/books.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>图书列表</title>
    </head>
    <body>
    </body>
    </html>
    
    http://192.168.1.11:8000/bookstore/books  #访问验证路由
    
    #补充books.html功能  
    #href="/bookstore/add_book" bookstore前加/ 从/  不加是当前页面
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>图书列表</title>
    </head>
    <body>
    <a href="/bookstore/add_book">添加图书</a>
    <table>
        <tr>
            <th>ID</th>
            <th>书名</th>
            <th>出版社</th>
            <th>定价</th>
            <th>零售价</th>
            <th>操作</th>
        </tr>
        {% for book in books %}
            <tr>
                <td>{{ book.id }}</td>
                <td>{{ book.title }}</td>
                <td>{{ book.pub }}</td>
                <td>{{ book.price }}</td>
                <td>{{ book.market_price }}</td>
                <td>
                    <a href="#">修改</a>
                    <a href="#">删除</a>
                </td>
            </tr>
        {% endfor %}
    </table>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    写添加功能/bookstore/add_book
    [root@vm mysite2]# vim mysite2/urls.py
     urlpatterns = [
       path('add_book/',include('add_book.urls')),
    
    
    [root@vm mysite2]# vim bookstore/urls.py
    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('add_book',views.add_book),
    ]
    
    
    [root@vm mysite2]# vim bookstore/views.py
    from django.shortcuts import render
    from django.http import HttpResponse, HttpResponseRedirect
    from .models import Book
    
    # Create your views here.
    def add_book(request):
        if request.method == 'GET':
            # 返回添加图书的页面
            return render(request,
                          'bookstore/add_book.html')
        elif request.method == 'POST':
            # return HttpResponse("添加图书成功!") #结合下方完整的add_book.html验证逻辑
           #OK了,再注释写下面的功能
            # 1.获取用户在add_book.html表单控件中输入的数据,
            title = request.POST['title']
            pub = request.POST['pub']
            price = request.POST['price']
            market_price = request.POST['market_price']
            # 2. 检查数据...
    
            # 3.添加到数据库
            Book.objects.create(title=title,
                                pub=pub,
                                price=price,
                                market_price=market_price)
    
            # 重定向到图书列表
            return HttpResponseRedirect('/bookstore/books')
    
    
    [root@vm mysite2]# vim bookstore/templates/bootstore/add_book.html
    #先验证title,再设计form表单
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>添加图书</title>  
    </head>
    <body>
    <form action="/bookstore/add_book" method="post">
        <p>书名:<input type="text" name="title"></p>
        <p>出版社:<input type="text" name="pub"></p>
        <p>定价:<input type="text" name="price"></p>
        <p>零售价:<input type="text" name="market_price"></p>
        <p><input type="submit" value="添加"></p>
    </form>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    修改和删除
      通过浏览器地址栏向服务器传参,方式有哪些?
      1. path转换器
      2. 查询字符串
    修改功能
            url:    http://127.0.0.1:8000/bookstore/update_book/1
            view: views.update_book 
            html:  "bookstore/update_book.html"
            models: Book类
    删除功能 
            url:    http://127.0.0.1:8000/bookstore/del_book?bid=1
            view: views.del_book 
            html:  "bookstore/del_book.html"
            models: Book类
      从业务角度谈谈删除问题?
      1. 真正删除时,一般要有提示信息?防止误删。
      2. 标记删除。常用!!!不是把数据真正的从数据库中删除掉,而是增加一个标记以示区分。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    [root@vm mysite2]# vim bookstore/urls.py
    from django.urls import path
    from . import views
    urlpatterns = [
        path('books',views.books_view),
        path('add_book',views.add_book),
        path('update_book/',views.update_book),#使用了path转换器,与查询字符串选其中一个使用
        path('del_book',views.del_book),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    [root@vm mysite2]# vim bookstore/views.py
    from django.http import HttpResponse, HttpResponseRedirect
    from django.shortcuts import render
    
    from .models import Book
    
    
    # Create your views here.
    def books_view(request):
        books = Book.objects.all()
        return render(request,
                      'bookstore/books.html',
                      locals())
    
    
    def add_book(request):
        if request.method == 'GET':
            # 返回添加图书的页面
            return render(request,
                          'bookstore/add_book.html')
        elif request.method == 'POST':
            # 1.获取用户在表单中输入的数据
            title = request.POST['title']
            pub = request.POST['pub']
            price = request.POST['price']
            market_price = request.POST['market_price']
            # 2. 检查数据...
    
            # 3.添加到数据库
            Book.objects.create(title=title,
                                pub=pub,
                                price=price,
                                market_price=market_price)
    
            # return HttpResponse("添加图书成功!")
            # 重定向到图书列表
            return HttpResponseRedirect('/bookstore/books')
    
    
    def update_book(request, bid):
        # 根据bid,从数据库中获取要修改的book对象
        # get,加try
        try:
            book = Book.objects.get(id=bid)
        except:
            return HttpResponse("图书编号有误!")
    
        if request.method == "GET":
            return render(request,
                          'bookstore/update_book.html',
                          locals())
        elif request.method == "POST":
            # 1查,【2改,3保存】
            # 获取用户输入的新的数据给属性赋值
            title = request.POST['title']
            pub = request.POST['pub']
            price = request.POST['price']
            market_price = request.POST['market_price']
    
            book.title = title
            book.pub = pub
            book.price = price
            book.market_price = market_price
            # 保存
            book.save()
            # return HttpResponse("修改图书成功!")
            # 重定向到图书列表
            return HttpResponseRedirect('/bookstore/books')
    
    
    def del_book(request):
        # 1.根据查询字符串获取图书ID.
        bid = request.GET.get('bid')
        # 2.根据图书ID获取图书对象
        try:
            book = Book.objects.get(id=bid)
            # 3.直接执行delete操作
            book.delete()
        except:
            return HttpResponse("图书ID有误!")
        # 4. 重定向到列表页
        return HttpResponseRedirect('/bookstore/books')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    [root@vm mysite2]# vim bookstore/templates/bookstore/books.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>图书列表</title>
    </head>
    <body>
    <a href="/bookstore/add_book">添加图书</a>
    <table>
        <tr>
            <th>ID</th>
            <th>书名</th>
            <th>出版社</th>
            <th>定价</th>
            <th>零售价</th>
            <th>操作</th>
        </tr>
        {% for book in books %}
            <tr>
                <td>{{ book.id }}</td>
                <td>{{ book.title }}</td>
                <td>{{ book.pub }}</td>
                <td>{{ book.price }}</td>
                <td>{{ book.market_price }}</td>
                <td>
                    <a href="/bookstore/update_book/{{ book.id }}">修改</a>
                    <a href="/bookstore/del_book?bid={{ book.id }}">删除</a>
                </td>
            </tr>
        {% endfor %}
    </table>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    [root@vm mysite2]# vim bookstore/templates/bookstore/update_book.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>修改图书</title>
    </head>
    <body>
    <form action="/bookstore/update_book/{{ book.id }}" method="post">
        <p>书名:<input type="text" name="title" value="{{ book.title }}"></p>
        <p>出版社:<input type="text" name="pub" value="{{ book.pub }}"></p>
        <p>定价:<input type="text" name="price" value="{{ book.price }}" ></p>
        <p>零售价:<input type="text" name="market_price"  value="{{ book.market_price }}" ></p>
        <p><input type="submit" value="修改"></p>
    </form>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    小的项目管理  
    	cMTV    运维数据整理
    
    企业级的项目
        前端T     
        基于文档,json格式数据,RESTful 接口规范,跨域问题解决
        后端cMV  python web     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    聚合查询

    聚合查询是指对一个数据表中的一个字段的数据进行部分或全部进行统计查询,查bookstore_book数据表中的全部书的平均价格,查询所有书的总个数等,都要使用聚合查询

    不带分组聚合

    不带分组的聚合查询是指导将全部数据进行集中统计查询,聚合函数【需要导入】,聚合函数有: Sum, Avg, Count, Max, Min

    from django.db.models import *
    MyModel.objects.aggregate(结果变量名=聚合函数('列'))
    
    • 1
    • 2

    返回结果:由 结果变量名和值组成的字典

    # 得到所有书的平均价格
    from bookstore.models import Book
    from django.db.models import *
    result = Book.objects.aggregate(myAvg=Avg('price'))
    print("result=", result)  # result= {'myAvg': Decimal('189.700000')}
    print("平均价格是:", result['myAvg']) #平均价格是: 189.700000
    
    # 得到数据表里有多少本书
    from django.db.models import Count
    result = Book.objects.aggregate(mycnt=Count('title'))
    print("result=", result)  #result= {'mycnt': 5}
    print("数据记录总个数是:", result['mycnt'])  #数据记录总个数是: 5
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    分组聚合(走两步)

    分组聚合是指通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值(也可以是平均值或总和),即为查询集的每一项生成聚合。

    1、通过先用查询结果MyModel.objects.values 查找查询要分组聚合的列,返回 QuerySet 结果集,内部存储结果的字典

    MyModel.objects.values('列1', '列2')
    
    • 1
    pub_set = Book.objects.values('pub')
    print(pub_set)  # 
    
    • 1
    • 2

    2、通过返回结果的 QuerySet.annotate 方法分组聚合得到分组结果

    QuerySet.annotate(结果变量名=聚合函数('列'))
    
    • 1
    pub_count_set = pub_set.annotate(myCount=Count('pub'),mysum=Sum('price'))
    print(pub_count_set)  <QuerySet [{'pub': '清华', 'myCount': 3, 'mysum': Decimal('160.50')}, {'pub': 'beida', 'myCount': 2, 'mysum': Decimal('788.00')}]>
    
    
    >>> for item in pub_count_set:
    ...     print(item['pub'],item['myCount'],item['mysum'])
    ...
    清华 3 160.50
    beida 2 788.00
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    F对象field

    一个F对象代表数据库中某条记录的字段的信息

    作用: 通常是对数据库中的字段值在不获取的情况下进行操作,用于类属性(字段)之间的比较。使用时需要先导入

    from django.db.models import F
    F('列名')  
    
    • 1
    • 2

    说明: 一个 F() 对象代表了一个model的字段的值,F对象通常是对数据库中的字段值在不加载到内存中的情况下(生成sql),直接在数据库服务器端进行操作

    基本使用

    更新Book实例中所有的零售价涨10元

    >>> from django.db.models import F
    >>> from bookstore.models import Book
    >>> Book.objects.all().update(market_price=F('market_price')+10)
    '''生成sql:UPDATE `bookstore_book` SET `market_price` = (`bookstore_book`.`market_price` + 10) '''
    5  #作用了5条数据
    
    # 以上做法好于如下代码,有循环读写,慢
    books = Book.objects.all()
    for book in books:
        book.market_price=book.marget_price+10
        book.save()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    使用查询谓词__gt

    对数据库中两个字段的值进行比较,列出哪儿些书的零售价高于定价?

    from django.db.models import F
    from bookstore.models import Book
    books = Book.objects.filter(market_price__gt=F('price'))
    'SELECT * FROM `bookstore_book` WHERE `bookstore_book`.`market_price` > (`bookstore_book`.`price`)
    for book in books:
        print(book.title, '定价:', book.price, '现价:', book.market_price)
        
    #go 定价: 88.00 现价: 108.00
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    Q对象query

    完整的表达逻辑操作,在条件中用来实现除 and(&) 以外的 or(|) 或 not(~) 操作,需要先导入再使用

    如: 想找出定价低于20元 或 清华大学出版社的全部书,可以写成

    from django.db.models import Q
    Q(条件1)|Q(条件2)  # 条件1成立或条件2成立
    Q(条件1)&Q(条件2)  # 条件1和条件2同时成立
    Q(条件1)&~Q(条件2)  # 条件1成立且条件2不成立
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    from django.db.models import Q
    # 查找清华大学出版社的书或价格低于50的书
    Book.objects.filter(Q(market_price__lt=50) | Q(pub='清华'))
    #, , , ]>
    
    # 查找不是机械工业出版社的书且价格低于50的书
    Book.objects.filter(Q(market_price__lt=50) & ~Q(pub='清华'))
    <QuerySet [<Book: 书名: xiyou, 出版社: beida, 定价: 700.00>]>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    原生的数据库操作方法

    模型管理器的raw

    在django中,可以使用模型管理器的raw方法来执行select语句进行数据查询

    MyModel.objects.raw(sql语句,[拼接参数])          #防止sql注入
    
    • 1

    返回值: RawQuerySet 集合对象 【只支持基础操作,比如循环】

    books = Book.objects.raw('select * from bookstore_book')
    for book in books:
        print(book)
    
    #sql注入攻击问题
    s1 = Book.objects.raw('select * from bookstore_book where id=%s'%('1 or 1=1'))
    #'select * from bookstore_book where id=%s'%(表单控件获得))
    #select * from bookstore_book where id=1 or 1=1;  id=1没有的时候,查询了所有
    >>> s1
    <RawQuerySet: select * from bookstore_book where id=1 or 1=1>
    >>> for book in s1:
    ...     print(book)
    ...
    书名: java, 出版社: 清华, 定价: 10.50
    书名: python, 出版社: 清华, 定价: 50.00
    书名: c++, 出版社: 清华, 定价: 100.00
    书名: xiyou, 出版社: beida, 定价: 700.00
    书名: go, 出版社: beida, 定价: 88.00
    
    #防止sql注入,拼接参数1 or之间的空格会发生截断,后面的不要
    s2 = Book.objects.raw('select * from bookstore_book where id=%s',['1 or 1=1'])
    >>> for book in s2:
    ...     print(book)
    ...
    书名: java, 出版社: 清华, 定价: 10.50    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    游标cursor

    使用django中的游标cursor直接对数据库进行 增删改查 操作,使用前需要先导入

    from django.db import connection
    
    • 1

    用创建cursor类的构造函数创建cursor对象,再使用cursor对象
    为保证在出现异常时能释放cursor资源,通常使用with语句进行创建操作

    from django.db import connection
    with connection.cursor() as cur:
        cur.execute('执行SQL语句', '拼接参数')
    
    • 1
    • 2
    • 3
    # 用SQL语句将id 为 10的 书的出版社改为 "XXX出版社"
    from django.db import connection
    with connection.cursor() as cur: 
        cur.execute('update bookstore_book set pub="XXX出版社" where id=10;')
    
    #拼接参数    
    with connection.cursor() as cur:
        cur.execute('update bookstore_book set pub="XXX出版社" where id=%s',['1 or 1=2'])
        
    # 删除 id为1的一条记录
    with connection.cursor() as cur:   
        cur.execute('delete from bookstore_book where id=10;')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    MySQL读写分离
    AI-数学-高中-43常见函数的导数
    webpack学习记录
    nexus部署私库及上传和拉包处理
    Typecho博客搭建+cpolar内网穿透实现公网访问内网站点
    【C语言】你真的了解printf吗?(printf典型易错,强烈建议收藏)
    The given SOAPAction http__xxxxx_xx does not match an operation
    python 科学计算三维可视化笔记(第一周 基础运用)
    Python----break关键字对while...else结构的影响
    C++基础知识要点--变量和基本类型
  • 原文地址:https://blog.csdn.net/weixin_60092693/article/details/131620747