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