Python学习之路―2018/6/29
跨表查询:
- 基于对象查询
- 基于双下划线查询
- 聚合和分组查询
- F与Q查询
过滤器只能讲字段值与常量进行比较,如果需要用到与字段值进行比较则需要用到F查询,F查询还支持与常量之间的加减乘除的运算。数据:
# 查询评论数大于阅读数的书籍 >>> Book.objects.filter(comment_count__gt=F("read_count")) <QuerySet [<Book: 斗破苍穹>, <Book: 吞噬星空>]> # 将所有书的价格提高10元 >>> Book.objects.all().update(price=F("price")+10)
过滤器中可以用逗号起到“和”的作用,如果想要用“或”的操作就需要用到Q查询
# 查询书籍名为斗破苍穹或者价格为130的 >>> Book.objects.filter(Q(title="斗破苍穹") | Q(price=130)) <QuerySet [<Book: 坏蛋是怎样炼成的>, <Book: 斗破苍穹>, <Book: 武动乾坤>]>主要有图书的增删改查四个功能,对应设置四个视图函数分别为add()、query()、edit()、delete()
分别有作者表(author),作者详细信息表(authordetail),图书表(book),出版社表(publish)以及作者图书关联表(book_authors)。
其中因为一个作者只有一个详细信息,所以作者表(author)与作者详细信息表(authordetail)是一对一关系;一个出版社可以出版多本书,所以图书表(book)与出版社表(publish)是一对多关系;一个出版社可以出版多个作者的书籍,而一位作者可以签约多个出版社,所以图书表(book)与作者表(author)是多对多关系。
models.py
from django.db import models class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() # 与AuthorDetail建立一对一关系 author_detail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE) def __str__(self): return self.name class AuthorDetail(models.Model): aid = models.AutoField(primary_key=True) birthday = models.DateField() telephone = models.BigIntegerField() addr = models.CharField(max_length=64) class Publish(models.Model): pid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField() def __str__(self): return self.name class Book(models.Model): bid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) publishDate = models.DateField() price = models.DecimalField(max_digits=5, decimal_places=2) # 与Publish建立一对多关系,外键字段建立在多的一方 publish = models.ForeignKey(to="Publish", to_field="pid", on_delete=models.CASCADE) """ publish_id INT, FOREIGN KEY(publish_id) REFERENCES publish(pid) """ # 与Author建立多对多关系 authors = models.ManyToManyField(to="Author") """ CREATE TABLE book_author( id INT PRIMARY KEY AUTO_INCREMENT, book_id INT, author_id INT, FOREIGN KEY(book_id) REFERENCES Book(bid), FOREIGN KEY(author_id) REFERENCES Author(nid), ) """ def __str__(self): return self.title为了使static文件夹下面的css、js文件生效,需要将static路径加入到STATICFILES_DIRS中
settings.py
STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static") ]views.py
from django.shortcuts import render, HttpResponse, redirect from .models import * def add(request): pub_list = Publish.objects.all() author_list = Author.objects.all() if request.method == "GET": return render(request, "add.html", locals()) elif 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") authors_list = request.POST.getlist("author") # getlist适用于多选的 # orm添加数据 Book.objects.create(title=title, publishDate=pub_date, price=price, publish_id=publish) book = Book.objects.get(title=title) book.authors.add(*authors_list) # 添加提交后回到图书界面 return redirect("/book") def book(request): book_list = Book.objects.all() return render(request, "book.html", locals()) def delete(request, bid): Book.objects.get(bid=bid).delete() return redirect("/book") def edit(request, bid): book_obj = Book.objects.filter(bid=bid) books = Book.objects.get(bid=bid) pub_list = Publish.objects.all() author_list = Author.objects.all() if request.method == "GET": return render(request, "edit.html", locals()) elif request.method == "POST": title = request.POST.get("title") price = request.POST.get("price") pub_date = request.POST.get("pub_date") authors_list = request.POST.getlist("author") book_obj.update(title=title, price=price, publishDate=pub_date) books.authors.set(authors_list) return redirect("/book")book.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>book</title> <link rel="stylesheet" href="/static/bootstrap.min.css"> <style type="text/css"> .table-bordered>thead>tr>th, .table-bordered>tbody>tr>td{ text-align: center; line-height: 33px; } </style> </head> <body> <h3>查看书籍</h3> <div class="container"> <div class="row"> <div class="col-md-8 col-lg-offset-2"> <table class="table table-bordered table-striped"> <thead> <tr> <th>名称</th> <th>价格</th> <th>出版日期</th> <th>出版社</th> <th>作者</th> <th>操作</th> </tr> </thead> <tbody> {# 根据传入的book_list,循环添加表数据 #} {% for book in book_list %} <tr> <td>{{ book.title }}</td> <td>{{ book.price }}</td> <td>{{ book.publishDate|date:"Y-m-d" }}</td> <td>{{ book.publish }}</td> <td>{% for i in book.authors.all %} {% if forloop.last %} <span>{{ i.name }}</span> {% else %} <span>{{ i.name }}</span>, {% endif %} {% endfor %} </td> <td> <a class="btn btn-primary" href="/edit/{{ book.bid }}">编辑</a> {# 传入book ID参数,便于在数据库中的表寻找数据后进行编辑和删除功能 #} <a class="btn btn-danger" href="/delete/{{ book.bid }}">删除</a> </td> </tr> {% endfor %} </tbody> </table> <a class="btn btn-default" href="/add">添加书籍</a> </div> </div> </div> </body> </html>
add.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>add</title> <link rel="stylesheet" href="/static/bootstrap.min.css"> </head> <body> {% block h3 %} <h3>添加书籍</h3> {% endblock %} <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form action="" method="post"> {% csrf_token %} <div class="form-group"> <label>名称</label> {% block title %} <input class="form-control" type="text" name="title"> {% endblock title %} </div> <div class="form-group"> <label>价格</label> {% block price %} <input class="form-control" type="text" name="price"> {% endblock price %} </div> <div class="form-group"> <label>出版日期</label> {% block pub_late%} <input class="form-control" type="date" name="pub_date"> {% endblock pub_late %} </div> <div class="form-group"> <label>出版社</label> <select class="form-control" name="publish"> {% for i in pub_list %} {% block publish %} <option value="{{ i.pk }}">{{ i.name }}</option> {% endblock %} {% endfor %} </select> </div> <div class="form-group"> <label>作者</label> <select class="form-control" name="author" multiple> {% for author in author_list %} {% block author %} <option value="{{ author.pk }}">{{ author.name }}</option> {% endblock %} {% endfor %} </select> </div> <input type="submit" class="btn btn-default"> </form> </div> </div> </div> </body> </html>
edit.html
继承add.html,重写block里的内容
{% extends "add.html" %} {% block h3 %} <h3>编辑书籍</h3> {% endblock %} {% block title %} {{ book_obj.title }} <input class="form-control" type="text" name="title" value="{{ books.title }}"> {% endblock %} {% block price %} <input class="form-control" type="text" name="price" value="{{ books.price }}"> {% endblock %} {% block pub_late%} <input class="form-control" type="date" name="pub_date" value="{{ books.publishDate|date:‘Y-m-d‘}}"> {% endblock %} {% block publish %} {# 通过传入的book出版社与所有出版社名字进行比较,相同的添加selected属性,起到编辑时的默认选中功能 #} {% if books.publish.name == i.name %} <option value="{{ i.pk }}" selected>{{ i.name }}</option> {% else %} <option value="{{ i.pk }}">{{ i.name }}</option> {% endif %} {% endblock %} {% block author %} {% if author in books.authors.all %} <option value="{{ author.pk }}" selected>{{ author.name }}</option> {% else %} <option value="{{ author.pk }}">{{ author.name }}</option> {% endif %} {% endblock %}
urls.py
from django.contrib import admin from django.urls import path, re_path from app01 import views urlpatterns = [ path(‘admin/‘, admin.site.urls), path(‘add/‘, views.add), path(‘book/‘, views.book), re_path(r‘^delete/(\d+)‘, views.delete), re_path(r‘^edit/(\d+)‘, views.edit) ]首先在浏览器中输入127.0.0.1:8080/book,到展示图书界面,接下来便可以操作添加、编辑、删除功能了。
原文:https://www.cnblogs.com/ExBurner/p/9245448.html