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 ...
随机推荐
- What IS MPI
一.MPI message passing interface A specification for the developers and users of message passing libr ...
- 使用velero进行kubernetes灾备
使用velero可以对集群进行备份和恢复,降低集群DR造成的影响.velero的基本原理就是将集群的数据备份到对象存储中,在恢复的时候将数据从对象存储中拉取下来.可以从官方文档查看可接收的对象存储,本 ...
- python3.7环境安装
wget http://mirror.centos.org/centos/6/os/x86_64/Packages/libffi-devel-3.0.5-3.2.el6.x86_64.rpm rpm ...
- 目标检测算法之Fast R-CNN和Faster R-CNN原理
一.Fast R-CNN原理 在SPPNet中,实际上特征提取和区域分类两个步骤还是分离的.只是使用ROI池化层提取了每个区域的特征,在对这些区域分类时,还是使用传统的SVM作为分类器.Fast R- ...
- Maven中的依赖相关总结
一.Maven的依赖作用域scope compile:编译.测试.运行都会依赖,会打进包中. rumtime:不存于编译,后期运行和测试都会参与,会打进包中. test:只在test classpat ...
- 阿里云Centos7用putty ssh链接掉线
解决方法:修改云服务器 ssh 配置文件(修改前一定要先备份) (1)打开配置文件: vim /etc/ssh/sshd_config 1 (2)找到下面两行: ClientAliveInterval ...
- python排序 基数排序
算法思想 基数排序通过按位比较(一般从最低位开始)将元素按照最低位的数放到10个桶中,当所有的元素都这样被处理一次后,在按从0到9的顺序将每个桶的元素再取出来(不关注其他位的,只关注当前位的)这样就完 ...
- SpringBoot 整合MyBatis 统一配置bean的别名
所谓别名, 就是在mappper.xml配置文件中像什么resultType="xxx" 不需要写全限定类名, 只需要写类名即可. 配置方式有两种: 1. 在 applicatio ...
- Springboot 项目源码 vue.js html 跨域 前后分离 shiro权限
官网:www.fhadmin.org 特别注意: Springboot 工作流 前后分离 + 跨域 版本 (权限控制到菜单和按钮) 后台框架:springboot2.1.2+ activiti6.0 ...
- Spring Boot2(八):性感banner,在线发牌
本文在个人技术博客[鸟不拉屎]同步发布,详情可猛戳 亦可扫描文章末尾二维码关注个人公众号[鸟不拉屎] emmm,没有啥前言 玩过SpringBoot的都知道,SpringBoot启动的时候,默认会在控 ...