zoukankan      html  css  js  c++  java
  • django-ORM单表操作

    1、ORM与数据库的关系

    Python语法SQL备注
     
    类属性 表字段  
    对象 表记录  

    2、Django 创建表

    class Books(models.Model):
        nid = models.AutoField(primary_key=True)
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=8, decimal_places=2)  # 最大值: 999999.99
        pub_date = models.DateTimeField()  # django 要求必须存这种格式:2019-07-12
        publish = models.CharField(max_length=32)

    执行数据库迁移命令,生成表:(在这之前请确保settings中配置了数据库连接,比如mysql,以及存在相应的database)

    3、配置Django连接MySQL数据库

    见:文档https://www.cnblogs.com/miaocbin/p/11311323.html

    4、ORM单表操作

    4.1 增加数据

    #
    ## 方式一:
    book = Book(title="python", price=123, pub_date="2019-9-22", publish="人民出版社")
    book.save()
    
    ## 方式二:推荐
    book = Book.objects.create(title="python", price=123, pub_date="2019-9-22", publish="人民出版社")
    print(book.title)
    ########### 添加书籍完整代码 ############
    def addbook(request):   # get请求拿数据,post请求提交数据
        if request.method == "POST":
            title = request.POST.get('title')
            price = request.POST.get('price')
            pub_date = request.POST.get('pub_date')
            publish = request.POST.get('publish')
            Books.objects.create(title=title, price=price, pub_date=pub_date, publish=publish)
            return redirect(reverse("books"))
        else:  # get请求,请求的是添加书籍的表单页面,返回addbook.html页面给用户
            return render(request, "addbook.html", locals())

    展示页面

    <!-- 书籍显示:完整的前端代码 -->
    <!-- Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">

    <!-- Bootstrap 核心 JavaScript 文件 -->
    <script src="/static/js/bootstrap.min.js"></script>
    <!-- 书籍添加:完整的前端代码 -->
    <h3>添加书籍</h3>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <!--action在此处硬编码了,也可以利用反向解析实现:action="{% url 'addbook' %}"-->
                <form action="/books/add/" method="post">   <!-- action 可以什么都不写,默认发到当前页面 -->
                    {% csrf_token %}
                    <div class="form-group"><label for="title">书籍名称</label>
                        <input type="text" class="form-control" id="title" placeholder="Title" name="title">
                    </div>
                    <div class="form-group"><label for="price">价格</label>
                        <input type="text" class="form-control" id="price" placeholder="Price" name="price">
                    </div>
                    <div class="form-group"><label for="pub_date">出版日期</label>
                        <input type="date" class="form-control" id="pub_date" placeholder="pub_date" name="pub_date">
                    </div>
                    <div class="form-group"><label for="publish">出版社</label>
                        <input type="text" class="form-control" id="publish" placeholder="publish" name="publish">
                    </div>
                    <button type="submit" class="btn btn-success pull-right">Submit</button>
                </form>
            </div>
        </div>
    </div>

    4.2 查询数据

    # 查 -- 用的最多,最繁琐的
    ## 查询所有,结果为QuerySet(特殊的列表),可以for循环,可以切片 取数据
    book_list = Book.objects.all()   # <QuerySet [<Books: Books object (1)>, <Books: Books object (2)>]>
    ## 条件查询
    book_list= Book.objects.filter(price=100) # 返回的结果也是 QuerySet
    
    ################# 完整的后端代码 #################
    def books(request):
        # 查询所有
        book_list = Books.objects.all()
        return render(request, "books.html", {"book_list": book_list})

    展示数据

    
    
    <!-- Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">

    <!-- Bootstrap 核心 JavaScript 文件 -->
    <script src="/static/js/bootstrap.min.js"></script>

    <!--
    书籍显示:完整的前端代码 --> <h3>书籍列表</h3> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <a href="/books/add/" class="btn btn-primary">添加书籍</a> <table class="table table-striped table-hover"> <!-- striped为斑马线,hover为悬浮效果--> <thead> <tr> <th>编号</th> <th>书籍名称</th> <th>价格</th> <th>出版日期</th> <th>出版社</th> <th>操作</th> </tr> </thead> <tbody> {% for book in book_list %} <tr> <td>{{ book.nid }}</td> <td>{{ book.title }}</td> <td>{{ book.price }}</td> <td>{{ book.pub_date|date:'Y-m-d'}}</td> <td>{{ book.publish }}</td> <td> <a href="/books/edit/{{ book.nid }}" class="btn btn-warning btn-sm">编辑</a> <!--href这里也是硬编码了,可以写成:href="{% url 'editbook' book.nid %}"--> <!-- 如果有多个动态参数,用空格隔开即可 --> <a href="/books/delete/{{ book.nid }}/" class="btn btn-danger btn-sm">删除</a> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div>

    4.3 删除数据

    # 删 -- 想删谁,要先查出来,要用到查询
    Book.objects.filter(nid=3).delete()   # 先找到要删除的结果(QuerySet),直接删除
    Book.objects.get(nid=7).delete()   # model对象,找到自己,然后删除
    ####### 完整的后端代码 ########
    def delbooks(request, delete_book_id):
        Books.objects.filter(nid=delete_book_id).delete()
        return redirect(reverse("books"))

    4.4 修改数据

    # 改,与删的语法都很简单,关键点在于查,怎么能够将要操作的记录给查出来,语法如下
    Books.objects.filter(nid=edit_book_id).update(price=120)  # http://127.0.0.1:8000/edit/9 就直接修改掉了
    Books.objects.filter(price=111).update(publish="南京出版社")
    return redirect("/books/")
    ############## 完整代码 ################
    def editbooks(request, edit_book_id):
        if request.method == "GET":
            edit_book = Books.objects.filter(nid=edit_book_id)[0]
            return render(request, "editbook.html", {"edit_book": edit_book})
        else:
            title = request.POST.get('title')
            price = request.POST.get('price')
            pub_date = request.POST.get('pub_date')
            publish = request.POST.get('publish')
            Books.objects.filter(nid=edit_book_id).update(title=title, price=price, pub_date=pub_date, publish=publish)
            return redirect(reverse("books"))

    展示数据

    <!-- Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    
    <!-- Bootstrap 核心 JavaScript 文件 -->
    <script src="/static/js/bootstrap.min.js"></script>
    
    <!-- 书籍编辑:完整的前端代码 -->
    
    <a href="#">编辑书籍</a>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <form action="" method="post">
                    <!-- action 可以什么都不写,默认发到当前页面 /books/edit/{{ edit_book.nid }} --> {% csrf_token %}
                    <div class="form-group"><label for="title">书籍名称</label> <input type="text" value="{{ edit_book.title }}"
                                                                                   class="form-control" id="title"
                                                                                   placeholder="Title" name="title"></div>
                    <div class="form-group"><label for="price">价格</label> <input type="text" value="{{ edit_book.price }}"
                                                                                 class="form-control" id="price"
                                                                                 placeholder="Price" name="price"></div>
                    <div class="form-group"><label for="pub_date">出版日期</label> <input type="date"
                                                                                      value="{{ edit_book.pub_date|date:'Y-m-d' }}"
                                                                                      class="form-control" id="pub_date"
                                                                                      placeholder="pub_date"
                                                                                      name="pub_date"></div>
                    <div class="form-group"><label for="publish">出版社</label> <input type="text"
                                                                                    value="{{ edit_book.publish }}"
                                                                                    class="form-control" id="publish"
                                                                                    placeholder="publish" name="publish">
                    </div>
                    <button type="submit" class="btn btn-success pull-right">Submit</button>
                </form>
            </div>
        </div>
    </div>

    5、美化显示模板

    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <style>
       .container {
            margin-top: 65px;
        }
    </style>

    6、URL路由配置

    from django.contrib import admin
    from django.urls import path, re_path
    from book import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('books/add/', views.addbook, name='addbook'),
        re_path('books/delete/(d+)/', views.delbooks, name='delbooks'),
        re_path('books/edit/(d+)/', views.editbooks, name='editbooks'),
        path('books/', views.books, name='books'),
        path('index/', views.index, name='index'),
    ]

    7、ORM 查询补充--单表查询API

    1. all() 查询所有结果

    2. filter() 带条件查询

    3. get() 查询结果只有一个,超过一个或没有都会报错(应用场景:)

    4. exclude() 查询与所给条件不匹配的对象

    5. order_by() 对查询结果排序

    6. reverse() 对查询结果倒序

    7. count() 返回匹配结果的个数

    8. first() 返回第一条记录

    9. last() 返回最后一条记录

    10. exists() 如果QuerySet包含数据返回True,否则返回False,bool值

    11. values() 返回一个特殊的Queryset,运行后得到的并不是一列model实例化对象,而是一个可迭代的字典序列

    12. values_list() 与values相似,返回的是一个元组序列,values返回的是一个字典序列

    13. distinct() 对查询结果去重

    # queryset
    # get()方法应用场景(它的特性决定了它的使用场景很特别)
    # 在上面的编辑书籍代码中的filter方法也可以换成get方法,因为用主键查询到的结果有且只有一个,不可能有重复的。又因为是编辑书籍,书籍也不可能不存在,所以这里用get方法很完美。
    edit_book = Books.objects.get(nid=edit_book_id)   # 使用get方法,利用要编辑书籍的id,找到要编辑的书籍操作
    
    # 1 all()  返回 QuerySet
    ret = Books.objects.all()  # <QuerySet [<Books: Python>, <Books: Shell>, <Books: GO>, <Books: ELK>]>
    print(ret)
    # 2 filter 返回 QuerySet
    ret = Books.objects.filter(title='linux')  # <QuerySet [<Books: linux>]>
    ret = Books.objects.filter(title='linux', price=23)  # <QuerySet [<Books: linux>]>
    print(ret)
    # 3 get() 返回查询到的 model对象,查到的结果有且只有一个才能正确返回,超过一个或不足一个就报错
    ret = Books.objects.get(title='linux')
    print(ret.title)   # model对象可以去点它的属性
    # 4 first(),last()方法 QuerySet调用,返回model对象
    fbook = Books.objects.all()[0]
    fbook = Books.objects.all().first()
    lbook = Books.objects.all().last()
    # 5 exclude() 返回 QuerySet
    ret = Books.objects.exclude(price=111)  # <QuerySet [<Books: Python>, <Books: ELK>, <Books: linux>]>
    print(ret)
    # 6 order_by() 返回 QuerySet
    ret = Books.objects.all().order_by("price")
    # 默认升序<QuerySet [<Books: linux>, <Books: ELK>, <Books: Python>, <Books: Shell>, <Books: GO>]>
    ret = Books.objects.all().order_by("-price")
    # 降序 <QuerySet [<Books: Shell>, <Books: GO>, <Books: Python>, <Books: ELK>, <Books: linux>]>
    print(ret)

    8、基于双下线的模糊查询

    Book.objects.filter(price__in=[100,200,300])
    Book.objects.filter(price__gt=100)
    Book.objects.filter(price__gte=100)
    Book.objects.filter(price__lt=100)
    Book.objects.filter(price__range=[100,200])
    Book.objects.filter(title__contains="python")
    Book.objects.filter(title__icontains="python")
    Book.objects.filter(title__startswith="py")
    Book.objects.filter(pub_date__year=2012)

    人们永远没有足够的时间把它做好,但永远有足够的时间重新来过。 可是,因为并不是总有机会重做一遍,你必须做得更好,换句话说, 人们永远没有足够的时间去考虑到底是不是想要它,但永远有足够的时间去为之后悔。 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ 浅掘千口井,不如深挖一口井!当知识支撑不了野心时,那就静下心来学习吧!运维技术交流QQ群:618354452

    个人微信公众号,定期发布技术文章和运维感悟。欢迎大家关注交流。

  • 相关阅读:
    /、./和../的区别
    【Java基础】-- FileUtils工具类常用方法
    【数据库】-- MySQL中比like更高效的三个写法
    【Java框架】-- SpringBoot大文件RestTemplate下载解决方案
    记一次gitlab代码仓清空还原复盘
    聊聊如何实现一个带有拦截器功能的SPI
    聊聊如何实现一个支持键值对的SPI
    类实例对象的class类型却不属于该类,何解?
    exe打包成安装文件(界面美观)
    linux系统软件启动sh脚本
  • 原文地址:https://www.cnblogs.com/miaocbin/p/11311438.html
Copyright © 2011-2022 走看看