django -- ORM实现图书增删改查
表结构设计
上篇我们实现了出版社的增删改查,出版社数据表有两个字段id和name,那图书的表结构怎么设计呢?图书也要有一个主键id,还要有一个名称title,是哪个出版社的,要有个字段press和Press表里的id对应,这样图书就需要三个字段,id,title,press
创建表
# 图书表
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32) # 书名
press = models.ForeignKey(to='Press',on_delete=models.CASCADE) # 和出版社表关联的字段
因为书和出版社是多对一的关系,一个出版社可以出版多个书,所以外键要写在多的这张表里面,也就是Book表里面
然后执行
python manage.py makemigrations
python manage.py migrate
说明:to='Press' 默认关联的是Press下的主键,on_delete=models.CASCADE级联删除,也就是如果你删除了出版社,Django会把你这个出版社关联的书都删掉。当然你也可以设置成null或者其他的默认值,不需要删除书。Django1.11中,默认就是级联删除,Django2.0之后必须指定on_delete
to=关联的表名,默认关联表里的主键,还有就是我们的字段是press,但是ORM在操作的时候,会在后面加上_id,在数据库里查看字段显示如下

获取表里的数据
我们往数据表里手动加些数据
url(r'^book_list/', views.book_list), # 展示图书列表
在去添加对应的函数
#获取图书列表返回给页面
def book_list(request):
#查询所有的书籍
data = Book.objects.all()
return render(request, 'book_list.html', {"data":data})
添加book_list.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书列表</title>
</head>
<body>
<table border="1">
<thead>
<tr>
<th>序号</th>
<th>书ID</th>
<th>书名</th>
<th>出版社名</th>
</tr>
</thead> <tbody>
{% for i in data %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ i.id }}</td>
<td>{{ i.title}}</td>
<td>{{ i.press.name }}</td>
</tr>
{% endfor %} </tbody>
</table> </body>
</html>
book_list.html
说明:
#查询所有的书籍
data = Book.objects.all()
#获取第一本书
first_book = data[0]
print(first_book) #Book表的对象 #取到对象的title属性
print(first_book.title) #取到对象的press属性
print(first_book.press) # press表的对象 #取到这本书关联的出版社的名称
print(first_book.press.name) #取到和我这本书关联的出版社id,也就是book表里的press_id
print(first_book.press_id) #连表查询到出版社id
print(first_book.press.id)
结果:
Book object
python从入门到放弃
Press object
北大出版社
15
15
增加图书
添加路由
url(r'^add_book/', views.add_book), # 添加图书
添加函数
#添加图书
def add_book(request):
if request.method == "POST":
#获取用户填写的书名
book_title = request.POST.get('book_title')
#获取用户选择的出版社id
pre_id = request.POST.get('press_id')
'''
基于外键对象的创建
press_obj=Press.objects.get(id=press_id)
Book.objects.create(title=book_title, press=press_obj)
'''
#基于外键id值的创建
Book.objects.create(title=book_title, press_id=pre_id)
return redirect('/book_list/') data = Press.objects.all()
return render(request, 'add_book.html', {"press_id": data})
添加add_book.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加书籍</title>
</head>
<body>
<h1>添加数据</h1>
<form action="/add_book/" method="post">
<input type="text" name="book_title">
<select name="press_id">
{% for press in press_id %}
<option value="{{ press.id }}">{{ press.name }}</option> {% endfor %} </select>
<input type="submit" value="添加">
</form> </body>
</html>
add_book.html
删除图书
在book_list.html里增加如下代码
{% for i in data %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ i.id }}</td>
<td>{{ i.title}}</td>
<td>{{ i.press.name }}</td>
<td>
<a href="/delete_book/?id={{ i.id }}">删除</a> 这句
</td>
</tr>
{% endfor %}
添加路由
url(r'^delete_book/', views.delete_book), # 删除图书
添加对应的函数
#删除图书
def delete_book(request):
delete_book_id = request.GET.get('id')
Book.objects.filter(id=delete_book_id).delete()
return redirect('/book_list/')
编辑图书
添加路由
url(r'^edit_book/', views.edit_book), # 编辑图书
添加对应的函数
# 编辑图书
def edit_book(request):
# 从url中取到要编辑的书籍的id值
edit_book_id = request.GET.get('id') # 根据id值找到要编辑的书籍对象
edit_book_obj = Book.objects.get(id=edit_book_id) if request.method == 'POST':
# 取到用户修改后的书籍名称和出版社信息
new_title = request.POST.get('book_title')
new_press_id = request.POST.get('press_id') # 修改书籍相应信息
edit_book_obj.title = new_title
edit_book_obj.press_id = new_press_id # 保存到数据库
edit_book_obj.save() return redirect('/book_list/') # 把所有的出版社查询出来
press_data = Press.objects.all()
return render(request,'edit_book.html', {'book_obj':edit_book_obj, 'press_list': press_data})
添加html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑书籍</title>
</head>
<body>
<h1>编辑书籍</h1>
<form action="" method="post">
<input type="text" name="book_title" value="{{book_obj.title }}"> <select name="press_id" >
{% for press in press_list %}
{% if book_obj.press == press %}
<option selected value="{{press.id }}">{{ press.name }}</option>
{% else %}
<option value="{{press.id }}">{{ press.name }}</option>
{% endif %} {% endfor %} </select>
<input type="submit" value="提交">
</form> </body>
</html>
总结
ORM外键
press = models.ForignKey(to='Press', on_delete=models.CASCADE)
查询
1. book_obj.press --> ORM层面封装的,返回的是和我这本书关联的出版社对象
2. book_obj.press_id --> 数据库中真正存在的字段,保存的是和我关联的出版社id值
编辑
Django模板语言中的if判断
{% if 条件 %}
满足时执行的语句
{% else %}
不满足时执行的语句
{% endif %}
django -- ORM实现图书增删改查的更多相关文章
- django -- ORM实现出版社增删改查
前戏 我们来完成一个图书管理系统的增删改查 表结构设计 1. 出版社 id name 2. 作者 id name 3. 书 id title 出版社_id 4. 作者_书_关系表 id 书 ...
- django -- ORM实现作者增删改查
前戏 前面我们已经实现了出版社的增删改查,书的增删改查,书和出版社的对应关系.现在来写一下作者的增删改查和书的对应关系,那书和作者有什么关系呢?一个作者可以写多本书,一本书可以有多个作者,所以书和作者 ...
- Django ORM记录的增删改查结合web端
模版语法分配变量 在views.py文件中定义一个视图函数show_data: def show_data(request): # 定义一个字典 并将它展示在前端HTML文件 user_dic = { ...
- Django项目的创建与介绍.应用的创建与介绍.启动项目.pycharm创建启动项目.生命周期.三件套.静态文件.请求及数据.配置Mysql完成数据迁移.单表ORM记录的增删改查
一.Django项目的创建与介绍 ''' 安装Django #在cmd中输入pip3 #出现这个错误Fatal error in launcher: Unable to create process ...
- [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]
[Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...
- 基于DRF的图书增删改查练习
功能演示 信息展示 添加功能 编辑功能 删除功能 DRF构建后台数据 本例的Model如下 from django.db import models class Publish(models.Mode ...
- 基于DRF的图书增删改查
功能演示 信息展示 添加功能 编辑功能 删除功能 DRF构建后台数据 本例的Model如下 from django.db import models class Publish(models.Mode ...
- 使用轻量级ORM Dapper进行增删改查
项目背景 前一段时间,开始做一个项目,在考虑数据访问层是考虑技术选型,考虑过原始的ADO.NET.微软的EF.NH等.再跟经理讨论后,经理强调不要用Ef,NH做ORM,后期的sql优化不好做,公司 ...
- Django之数据表增删改查
Django数据增删改查: 上课代码 from django.shortcuts import render,HttpResponse # Create your views here. from a ...
随机推荐
- Rancher 部署 loonflow 工单系统
上篇文章介绍用实例主机部署:https://www.cnblogs.com/weavepub/p/11672305.html,本文采用Rancher上部署. 文章所有的文件都托管在Github:htt ...
- Nginx 变量参数
$args #请求中的参数值 $query_string #同 $args $arg_NAME #GET请求中NAME的值 $is_args #如果请求中有参数,值为"?",否则为 ...
- cookie、session和token的概念
Cookie.Session和Token都是为了解决Web身份校验而产生的,这里对它们的概念做一个简单了解. Web身份校验的发展 很久很久以前,Web基本上就是文档的浏览而已.既然是浏览,作为服务器 ...
- UWP 使用Launcher 启动迅雷
不得不说UWP有些地方真的不方便! 另外也要夸一下迅雷,还是蛮不错的! 代码 await Launcher.LaunchUriAsync(new Uri("magnet:?xt") ...
- [转] Performance — 前端性能监控利器
timing (PerformanceTiming) 从输入url到用户可以使用页面的全过程时间统计,会返回一个PerformanceTiming对象,单位均为毫秒 按触发顺序排列所有属性:(更详细标 ...
- window下使用curl操作elasticsearch
1.下载curlzip,https://curl.haxx.se/download.html; 2.解压,在bin文件夹中找到curl.exe,右键“以管理员身份运行”,cmd e: 换盘符:出现E: ...
- 数据库xp_cmdshell使用
首先也开启组件. sp_configure reconfigure go sp_configure reconfigure go 删除本地文件,注意是删除数据库所在的服务器的本地文件. exec ma ...
- Python轮子
代码复用 会用到的轮子贴在这篇文章中,备用.
- delphi实现窗体闪烁功能
delphi实现窗体闪烁功能 以前做窗口闪动时都没有考虑到让任务栏上的按钮闪动的问题, 现在一个客户需要任务栏按钮闪动,发现以前使用的flashwindow不能达到要求了, 查找了一下,找到flash ...
- 实验吧——你真的会PHP吗?(intval范围 php中\00的利用)
题目地址:http://ctf5.shiyanbar.com/web/PHP/index.php 抓包在header中发现提示 访问得到源码 <?php $info = "" ...