Django增删改查--图书管理系统
一对一 出版社信息的增删改查
一对多 出版社信息与书籍信息的增删改查
多对多 书籍信息与作者信息的增删改查
建表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.db import models class Publisher(models.Model): pid = models.AutoField(primary_key=True) # 自增字段且设置为主键 name = models.CharField(max_length=32,unique=True) # 设置唯一 def __str__(self): return "{}--{}".format(self.pid,self.name) class Book(models.Model): name = models.CharField(max_length=32,unique=True) pub = models.ForeignKey('Publisher',on_delete=models.CASCADE) # 外键 要链接的类名可以直接写,也可以写在字符串内 级联删除 class Author(models.Model): name = models.CharField(max_length=32) books = models.ManyToManyField('Book') # 多对多,生成第三张表
一对一
1.设计URL
URL
2.写函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from app01 import models def publisher_list(request): '''展示数据''' # 获取数据库内所有出版社的数据 publishers = models.Publisher.objects.all().order_by('pid') # 获取对象列表并按照pid字段排序 return render(request,'publisher_list.html',{'publishers':publishers}) # 第三个参数是为了给html文件传值调用 def add_publisher(request): '''新增数据''' if request.method == 'POST': # 获取提交的数据(括号内为input的name属性值),没有默认空字符串 new_name = request.POST.get('new_name','').strip() # 设定输入不能为空 if not new_name: return render(request,'add_publisher.html',{'err_msg':'输入不能为空','name':new_name}) # 设定不能与数据库现有数据重复 obj_list = models.Publisher.objects.filter(name=new_name) # 在数据库中查询数据是否存在 if obj_list: # 数据重复 return render(request, 'add_publisher.html', {'err_msg': '出版社名称已存在', 'name': new_name}) # orm往数据库中写入数据 if new_name and not obj_list: models.Publisher.objects.create(name=new_name) return redirect('/publisher_list/') # 如果不是post请求,还是返回本页面 return render(request,'add_publisher.html') def delete_publisher(request): '''删除数据''' # 找到需要删除的数据的id pk = request.GET.get('pk') # 通过id在数据库中找到对应的数据 obj = models.Publisher.objects.filter(pid=pk) # 如果数据不存在(通过地址栏指定id进行删除) if not obj: return HttpResponse('要编辑的数据不存在') # 删除数据 返回展示页面 obj.delete() return redirect('/publisher_list/') def edit_publisher(request): # 找到需要编辑的数据的id pk = request.GET.get('pk') # 通过id在数据库中找到对应的数据 对象列表<QuerySet [<Publisher: 1--人民邮电出版社>]> obj_list = models.Publisher.objects.filter(pk=pk) # 如果数据不存在(通过地址栏指定id进行编辑) if not obj_list: return HttpResponse('要编辑的数据不存在') # 拿到数据 1--人民邮电出版社 obj = obj_list[0] err_msg = '' if request.method == 'POST': # 获取用户输入的数据 new_name = request.POST.get('new_name','').strip() # 设定输入不能为空,返回添加页面 if not new_name: err_msg = '输入不能为空' # return render(request, 'edit_publisher.html', {'obj': obj, 'err_msg': '输入不能为空'}) # 设定不能与数据库现有数据重复 obj_list = models.Publisher.objects.filter(name=new_name) # 在数据库中查询数据是否存在 if obj_list: #有重复数据,返回添加页面 err_msg = '出版社名称已存在' # return render(request, 'edit_publisher.html', {'obj': obj, 'err_msg': '出版社名称已存在'}) #修改数据 if new_name and not obj_list: obj.name = new_name # 在内存中修改 obj.save() # 写入数据库 return redirect('/publisher_list/') #跳转到展示页面 return render(request,'edit_publisher.html',{'obj':obj,'err_msg':err_msg}) return render(request, 'edit_publisher.html')
3.写模板
{{ 变量 }},可以使用函数传的参数进行渲染
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<html lang="en"> <head> <meta charset="UTF-8"> <title>出版社信息</title> <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"> </head> <body> <div class="container"> <a class="btn btn-success" href="/add_publisher/" role="button">新增</a> <table class="table table-condensed"> <thead> <tr> <th>序号</th> <th>ID</th> <th>名称</th> <th>操作</th> </tr> </thead> <tbody> {% for foo in publishers %} # 开始循环 <tr> <td>{{ forloop.counter }}</td> <td>{{ foo.pk }}</td> <td>{{ foo.name }}</td> <td> <a class="btn btn-info" href="/delete_publisher/?pk={{ foo.pk }}" role="button">删除</a> <a class="btn btn-info" href="/edit_publisher/?pk={{ foo.pk }}" role="button">编辑</a> </td> </tr> {% endfor %} # 结束循环 </tbody> </table> </div> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<html lang="en"> <head> <meta charset="UTF-8"> <title>添加信息</title> <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"> </head> <body> <div class="container"> <form class="form-horizontal" method="post" action=""> <div class="form-group"> <label for="inputName3" class="col-sm-2 control-label">名称</label> <div class="col-sm-5"> <input type="text" class="form-control" name="new_name" placeholder="出版社名称" value="{{ name }}"> <span>{{ err_msg }}</span> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交</button> </div> </div> </form> </div> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>编辑信息</title> <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"> </head> <body> <div class="container"> <form class="form-horizontal" method="post" action=""> <div class="form-group"> <label for="inputName3" class="col-sm-2 control-label">名称</label> <div class="col-sm-5"> <input type="text" class="form-control" name="new_name" value="{{ obj.name}}"> <span>{{ err_msg }}</span> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交</button> </div> </div> </form> </div> </body> </html>
一对多
1.设计URL
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^publisher_list/', views.publisher_list),
url(r'^add_publisher/', views.add_publisher),
url(r'^delete_publisher/', views.delete_publisher),
url(r'^edit_publisher/', views.edit_publisher),
url(r'^book_list/', views.book_list),
url(r'^add_book/', views.add_book),
url(r'^del_book/', views.del_book),
url(r'^edit_book/', views.edit_book),
]
2.写函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def book_list(request): '''书籍数据展示''' # 将数据库中的数据读取出来 books = models.Book.objects.all() #对象列表 return render(request,'book_list.html',{'books':books}) def add_book(request): '''添加书籍信息''' # 获取所有出版社信息 publishers = models.Publisher.objects.all() if request.method == 'POST': # 获取提交的数据 new_name = request.POST.get('new_name','').strip() pub_id = request.POST.get('pub_id') err_msg = '' # 不能为空 if not new_name: err_msg = '输入不能为空' # 不能与现有书籍重复 obj = models.Book.objects.filter(name=new_name) if obj: err_msg = '书籍已存在' # 写入数据库 if new_name and not obj: models.Book.objects.create(name=new_name,pub_id=pub_id) # 跳转到展示页面 return redirect('/book_list/') return render(request,'add_book.html',{'publishers':publishers,'err_msg':err_msg,'new_name':new_name}) # 如果不是post请求 return render(request,'add_book.html',{'publishers':publishers}) def del_book(request): '''删除书籍''' # 获取删除数据的pk pk = request.GET.get('pk') # 根据pk在数据库中找出对应的数据 obj = models.Book.objects.filter(pk=pk) # 如果pk不存在 if not obj: return HttpResponse('要删除的数据不存在') # 删除数据 obj.delete() # 返回展示页面 return redirect('/book_list/') def edit_book(request): '''编辑书籍信息''' # 找到需要编辑数据的pk pk = request.GET.get('pk') #根据pk找到数据库中的对应的数据 obj_list = models.Book.objects.filter(pk=pk) obj = obj_list[0] publishers = models.Publisher.objects.all() if request.method == 'POST': # 获取提交的数据 new_name = request.POST.get('new_name','').strip() pub_id = request.POST.get('pub_id','').strip() err_msg = '' if not new_name: err_msg = '输入不能为空' book_obj = models.Book.objects.filter(name=new_name) if book_obj: err_msg = '书籍已存在' if new_name and not book_obj: obj.name = new_name obj.pub_id = pub_id obj.save() return redirect('/book_list/') return render(request,'edit_book.html',{'err_msg':err_msg,'obj':obj,'publishers':publishers}) return render(request,'edit_book.html',{'publishers':publishers,'obj':obj})
3.写模板
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>书籍信息</title> <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"> </head> <body> <div class="container"> <div class="panel panel-primary" style="margin-top: 50px"> <div class="panel-heading">书籍信息</div> <div class="panel-body"> <a class="btn btn-primary" href="/add_book/" role="button">新增</a> <table class="table table-condensed"> <thead> <tr> <th>序号</th> <th>ID</th> <th>书名</th> <th>出版社</th> <th>操作</th> </tr> </thead> <tbody> {% for book in books %} <tr> <td>{{ forloop.counter }}</td> <td>{{ book.pk }}</td> <td>{{ book.name }}</td> <td>{{ book.pub.name }}</td> <td> <a class="btn btn-danger" href="/del_book/?pk={{ book.pk }}" role="button">删除</a> <a class="btn btn-success" href="/edit_book/?pk={{ book.pk }}" role="button">编辑</a> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>添加书籍信息</title> <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"> </head> <body> <div class="container"> <div class="panel panel-primary" style="margin-top: 50px"> <div class="panel-heading">添加书籍信息</div> <div class="panel-body"> <form class="form-horizontal" method="post" action=""> <div class="form-group"> <label for="inputName3" class="col-sm-2 control-label">书名</label> <div class="col-sm-5"> <input type="text" class="form-control" name="new_name" placeholder="书名" value="{{ new_name }}"> <span>{{ err_msg }}</span> </div> </div> <div class="form-group"> <label for="inputName3" class="col-sm-2 control-label">出版社</label> <div class="col-sm-5"> <select name="pub_id" id="" class="form-control"> {% for publisher in publishers %} <option value="{{ publisher.pk }}">{{ publisher.name }}</option> <span>{{ err_msg }}</span> {% endfor %} </select> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交</button> </div> </div> </form> </div> </div> </div> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>编辑书籍信息</title> <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"> </head> <body> <div class="container"> <div class="panel panel-primary" style="margin-top: 50px"> <div class="panel-heading">编辑书籍信息</div> <div class="panel-body"> <form class="form-horizontal" method="post" action=""> <div class="form-group"> <label for="inputName3" class="col-sm-2 control-label">书名</label> <div class="col-sm-5"> <input type="text" class="form-control" name="new_name" value="{{ obj.name }}"> <span>{{ err_msg }}</span> </div> </div> <div class="form-group"> <label for="inputName3" class="col-sm-2 control-label">出版社</label> <div class="col-sm-5"> <select name="pub_id" id="" class="form-control"> {% for publisher in publishers %} {% if publisher == obj.pub %} <option selected value="{{ publisher.pk }}">{{ publisher.name }}</option> {% else %} <option value="{{ publisher.pk }}">{{ publisher.name }}</option> {% endif %} {% endfor %} </select> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交</button> </div> </div> </form> </div> </div> </div> </body> </html>
多对多
1.设计URL
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^publisher_list/', views.publisher_list),
url(r'^add_publisher/', views.add_publisher),
url(r'^delete_publisher/', views.delete_publisher),
url(r'^edit_publisher/', views.edit_publisher),
url(r'^book_list/', views.book_list),
url(r'^add_book/', views.add_book),
url(r'^del_book/', views.del_book),
url(r'^edit_book/', views.edit_book),
url(r'^author_list/', views.author_list),
url(r'^add_author/', views.add_author),
url(r'^del_author/', views.del_author),
url(r'^edit_author/', views.edit_author),
]
2.写函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def author_list(request): '''展示作者''' authors = models.Author.objects.all() # for i in authors: # print(i.books) # 关系管理对象 # print(i.books.all()) # 关联的书籍对象 return render(request,'author_list.html',{'authors':authors}) def add_author(request): '''新增作者''' if request.method == 'POST': name = request.POST.get('name') book_id = request.POST.getlist('book_id') # get方法只会取一条数据,书籍为多选,使用getlist方法,结果为列表 # 写入数据库,返回展示页面 author_obj = models.Author.objects.create(name=name) # 创建作者对象 author_obj.books.set(book_id) # set方法 设置作者和书籍的多对多的关系 每次都是重新设置.删除原有数据,生成新的id return redirect('/author_list/') books = models.Book.objects.all() return render(request,'add_author.html',{'books':books}) def del_author(request): '''删除作者''' pk = request.GET.get('pk') models.Author.objects.filter(pk=pk).delete() return redirect('/author_list/') def edit_author(request): '''编辑作者''' pk = request.GET.get('pk') edit_obj = models.Author.objects.get(pk=pk) if request.method == 'POST': name = request.POST.get('name') books_id = request.POST.getlist('book_id') edit_obj.name = name edit_obj.save() edit_obj.books.set(books_id) # 修改作者与书籍的多对多关系 return redirect('/author_list/') books = models.Book.objects.all() return render(request,'edit_author.html',{'obj':edit_obj,'books':books})
3.写模板
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>作者信息</title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.css"> </head> <body> <div class="container"> <div class="panel panel-primary" style="margin-top: 50px"> <div class="panel-heading"><h4>作者信息</h4></div> <div class="panel-body"> <a class="btn btn-primary" href="/add_author/" role="button">新增</a> <table class="table table-condensed"> <thead> <tr> <th>序号</th> <th>ID</th> <th>作者</th> <th>代表作</th> <th>操作</th> </tr> </thead> <tbody> {% for author in authors %} <tr> <td>{{ forloop.counter }}</td> <td>{{ author.pk }}</td> <td>{{ author.name }}</td> <td> {% for book in author.books.all %} {{ book.name }} {% endfor %} </td> <td> <a class="btn btn-danger" href="/del_author/?pk={{ author.pk }}" role="button">删除</a> <a class="btn btn-success" href="/edit_author/?pk={{ author.pk }}" role="button">编辑</ </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>添加作者信息</title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.css"> </head> <body> <div class="container"> <div class="panel panel-primary" style="margin-top: 50px"> <div class="panel-heading">添加作者信息</div> <div class="panel-body"> <form class="form-horizontal" method="post" action=""> <div class="form-group"> <label for="inputName3" class="col-sm-2 control-label">姓名</label> <div class="col-sm-5"> <input type="text" class="form-control" name="name" placeholder="姓名"> <span>{{ err_msg }}</span> </div> </div> <div class="form-group"> <label for="inputName3" class="col-sm-2 control-label">代表作</label> <div class="col-sm-5"> <select name="book_id" id="" class="form-control" multiple> {% for book in books %} <option value="{{ book.pk }}">{{ book.name }}</option> {% endfor %} </select> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交</button> </div> </div> </form> </div> </div> </div> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>修改作者信息</title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.css"> </head> <body> <div class="container"> <div class="panel panel-primary" style="margin-top: 50px"> <div class="panel-heading">编辑作者信息</div> <div class="panel-body"> <form class="form-horizontal" method="post" action=""> <div class="form-group"> <label for="inputName3" class="col-sm-2 control-label">姓名</label> <div class="col-sm-5"> <input type="text" class="form-control" name="new_name" value="{{ obj.name }}"> </div> </div> <div class="form-group"> <label for="inputName3" class="col-sm-2 control-label">代表作</label> <div class="col-sm-5"> <select name="book_id" id="" class="form-control" multiple> {% for book in books %} {% if book in obj.books.all %} <option selected value="{{ book.pk }}">{{ book.name }}</option> {% else %} <option value="{{ book.pk }}">{{ book.name }}</option> {% endif %} {% endfor %} </select> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交</button> </div> </div> </form> </div> </div> </div> </body> </html>
创建多对多关系的三种方式
1.Django创建第三张表
class Author(models.Model): name = models.CharField(max_length=32) books = models.ManyToManyField('Book') # 表示多对多的关系 生成第三张表
2.自己创建第三张表
可以在第三张表中添加另外的字段和数据,利用django直接创建是做不到的,但是查询数据比较复杂
class Author(models.Model): name = models.CharField(max_length=32) class Author_Book(models.Model): author = models.ForeignKey('Author') book = models.ForeignKey('Book') time = models.CharField(max_length=32)
3.Django + 自建表
通过Django和自建表的形式,既可以在表中添加字段和数据,也解决了查询困难的事情
class Author(models.Model): name = models.CharField(max_length=32) books = models.ManyToManyField('Book',through='Author_Book') # 表示多对多的关系 class Author_Book(models.Model): author = models.ForeignKey('Author') book = models.ForeignKey('Book') time = models.CharField(max_length=32)