1>效果
如下,3个html文件,两个页面(添加和删除基本一样),各个按钮实现对应的增删改查功能。
思路:1>查看书籍页面:从数据库找到所有的书籍对象,html循环对象取值,显示书籍信息,
多对多的作者,html中通过书本对象取对应的作者信息(注意正反向),因为可能有多个值,循环取
一对多的出版社,html中通过书本对象取对应的出版社信息(注意正反向),
2>添加书籍:页面输入信息,点击提交后,post请求会包含这些数据的键值对,
添加书籍 直接就是单表操作了,新增数据,注意有个出版社的值,这里写入的是对应的id
多对多写入作者信息,应用之前的语法 书本对象。关联字段。add(对象1,对象2.。。)
3>编辑书籍,编辑按钮的a标签会把这条记录的主键值传入url,所以根据url接收的参数可以筛选出书本记录
这该条记录的值 写入编辑页面对应的数据框,要注意的是出版社和作者,首先HTML取值还是遵循之前的多表
操作,正向靠字段,反向靠表名,再判断下哪些值跟这条记录的值一致,就加上selected样式标识。
然后修改信息并提交,书籍表直接update,注意作者表,因之前就存在一些关联数据,作者表的处理方式应该是
先删除之前的关联关系数据,再写入新的。
4> 删除书籍,这个就跟之前单表操作一样了,通过删除a标签发送到url的标识值,找到该记录并删除。
2>具体代码如下
2.1>路由层,建立path跟视图函数的映射关系
from django.contrib import admin from django.urls import path, re_path from book2.views import * urlpatterns = [ path('admin/', admin.site.urls), path('addbook/', addbook), path('books/', books), re_path(r"books/(\d+)/delete",delbook) ,# delbook(request,1) re_path(r"books/(\d+)/change",changebook) ,# delbook(request,1) ]
2.2>视图层,视图函数
from django.shortcuts import render, redirect # Create your views here. from book2.models import * # 添加书籍 def addbook(request): # 查找所有的出版社对象 pub_list = Publish.objects.all() # 查找所有的作者对象 author_list = Author.objects.all() if request.method=="POST": print(request.POST) title = request.POST.get("title") price = request.POST.get("price") publish_id = request.POST.get("pub") author_id_list = request.POST.getlist("author") # checkbox,多选select等需要用此方法 # 插入书籍数据(单表操作) book_obj = Book.objects.create(title=title,price=price,publish_id=publish_id) # 要么用publish传入一个实例,要么用publish_id传入对应的主键值 # 插入book_author关系表数据(多对多数据插入) book_obj.authors.add(*author_id_list) return redirect("/books/") return render(request,"addbook.html", locals()) # 主页显示所有书籍 def books(request): book_list=Book.objects.all() return render(request,"books.html",locals()) # 编辑书籍信息 def changebook(request,id): # 查找所有的出版社对象 pub_list = Publish.objects.all() # 查找所有的作者对象 author_list = Author.objects.all() # 查找对应的书籍对象 book_obj=Book.objects.filter(nid=id).first() if request.method=="POST": print(request.POST) title = request.POST.get("title") price = request.POST.get("price") publish_id = request.POST.get("pub") author_id_list = request.POST.getlist("author") # checkbox,多选select等需要用此方法 # 更新书籍数据和关联数据 Book.objects.filter(nid=id).update(title=title,price=price,publish_id=publish_id) # 要么用publish传入一个实例,要么用publish_id传入对应的主键值 book_obj.authors.clear() # 清空关联关系数据,再写入新的 book_obj.authors.add(*author_id_list) return redirect("/books/") return render(request,"changebook.html",locals()) # 删除书籍 def delbook(request,id): Book.objects.filter(nid=id).delete() return redirect("/books/")
2.3>控制层,控制显示
添加书本的html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 新 Bootstrap 核心 CSS 文件 --> <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <style> .container{ margin-top: 100px; } .btn{ margin-top: 10px; } </style> </head> <body> <h3>添加书籍</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <form action="" method="post"> {% csrf_token %} <div> <label for="">书籍名称</label> <input type="text" class="form-control" name="title"> </div> <div> <label for="">价格</label> <input type="text" class="form-control" name="price"> </div> <div> <label for="" >作者</label> <select class="form-control" multiple name="author"> {% for author in author_list %} <option value ='{{ author.pk }}'>{{ author.name }}</option> {% endfor %} </select> </div> <div> <label for="">出版社</label> <select class="form-control" name="pub"> {% for pub in pub_list %} <option value ="{{ pub.pk }}">{{ pub.name }}</option> {% endfor %} </select> </div> <input type="submit" class="btn btn-success pull-right"> </form> </div> </div> </div> </body> </html>
书本显示html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 新 Bootstrap 核心 CSS 文件 --> <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <style> .container{ margin-top: 100px; } .btn{ margin-top: 10px; } </style> </head> <body> <h3>查看书籍</h3> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-3"> <a href="/addbook/" class="btn btn-primary">添加书籍</a> <table class="table table-striped table-bordered"> <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.title }}</td> <td>{{ book.price }}</td> <td> {% for author in book.authors.all %} {% if forloop.last %} <span>{{ author.name }}</span> {% else %} <span>{{ author.name }}</span>、 {% endif %} {% endfor %} </td> <td>{{ book.publish.name }}</td> <td><a href="/books/{{ book.pk }}/change" class="btn btn-info">编辑</a></td> <td><a href="/books/{{ book.pk }}/delete" class="btn btn-danger">删除</a></td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>
编辑书本的HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 新 Bootstrap 核心 CSS 文件 --> <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <style> .container{ margin-top: 100px; } .btn{ margin-top: 10px; } </style> </head> <body> <h3>编辑书籍</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <form action="" method="post"> {% csrf_token %} <div> <label for="">书籍名称</label> <input type="text" class="form-control" name="title" value="{{ book_obj.title }}"> </div> <div> <label for="">价格</label> <input type="text" class="form-control" name="price" value="{{ book_obj.price }}"> </div> <div> <label for="" >作者</label> <select class="form-control" multiple name="author"> {% for author in author_list %} {% if author in book_obj.authors.all %} <option value ='{{ author.pk }}' selected>{{ author.name }}</option> {% else %} <option value ='{{ author.pk }}'>{{ author.name }}</option> {% endif %} {% endfor %} </select> </div> <div> <label for="">出版社</label> <select class="form-control" name="pub"> {% for pub in pub_list %} {% if pub.name == book_obj.publish.name %} <option value ="{{ pub.pk }}" selected>{{ pub.name }}</option> {% else %} <option value ="{{ pub.pk }}">{{ pub.name }}</option> {% endif %} {% endfor %} </select> </div> <input type="submit" class="btn btn-success pull-right"> </form> </div> </div> </div> </body> </html>
2.4>模型层,数据库交互
from django.db import models # Create your models here. class Author(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) age=models.IntegerField() # 与AuthorDetail建立一对一的关系 authorDetail=models.OneToOneField(to="AuthorDetail",to_field='nid', on_delete=models.CASCADE) def __str__(self): return self.name class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday=models.DateField() telephone=models.BigIntegerField() addr=models.CharField( max_length=64) class Publish(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField( max_length=32) price=models.DecimalField(max_digits=5,decimal_places=2) # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors=models.ManyToManyField(to='Author',) # 与Publish建立一对多的关系,外键字段建立在多的一方 publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE) def __str__(self): return self.title