1、ORM与数据库的关系
Python语法 | SQL | 备注 |
---|---|---|
类 | 表 | |
类属性 | 表字段 | |
对象 | 表记录 |
2、
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、
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())
展示页面
<!-- 书籍显示:完整的前端代码 --> <!-- 书籍添加:完整的前端代码 --> <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})
展示数据
<!-- 书籍显示:完整的前端代码 --> <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"))
展示数据
<!-- 书籍编辑:完整的前端代码 --> <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/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <style> .container { margin-top: 65px; } </style>
6、
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、
-
-
filter() 带条件查询
-
get() 查询结果只有一个,超过一个或没有都会报错(应用场景:)
-
exclude() 查询与所给条件不匹配的对象
-
order_by() 对查询结果排序
-
reverse() 对查询结果倒序
-
count() 返回匹配结果的个数
-
first() 返回第一条记录
-
last() 返回最后一条记录
-
exists() 如果QuerySet包含数据返回True,否则返回False,bool值
-
values() 返回一个特殊的Queryset,运行后得到的并不是一列model实例化对象,而是一个可迭代的字典序列
-
values_list() 与values相似,返回的是一个元组序列,values返回的是一个字典序列
-
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)
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)