表结构设计

上篇我们实现了出版社的增删改查,出版社数据表有两个字段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实现图书增删改查的更多相关文章

  1. django -- ORM实现出版社增删改查

    前戏 我们来完成一个图书管理系统的增删改查 表结构设计 1. 出版社 id   name 2. 作者 id  name 3. 书 id  title  出版社_id 4. 作者_书_关系表 id  书 ...

  2. django -- ORM实现作者增删改查

    前戏 前面我们已经实现了出版社的增删改查,书的增删改查,书和出版社的对应关系.现在来写一下作者的增删改查和书的对应关系,那书和作者有什么关系呢?一个作者可以写多本书,一本书可以有多个作者,所以书和作者 ...

  3. Django ORM记录的增删改查结合web端

    模版语法分配变量 在views.py文件中定义一个视图函数show_data: def show_data(request): # 定义一个字典 并将它展示在前端HTML文件 user_dic = { ...

  4. Django项目的创建与介绍.应用的创建与介绍.启动项目.pycharm创建启动项目.生命周期.三件套.静态文件.请求及数据.配置Mysql完成数据迁移.单表ORM记录的增删改查

    一.Django项目的创建与介绍 ''' 安装Django #在cmd中输入pip3 #出现这个错误Fatal error in launcher: Unable to create process ...

  5. [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]

    [Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...

  6. 基于DRF的图书增删改查练习

    功能演示 信息展示 添加功能 编辑功能 删除功能 DRF构建后台数据 本例的Model如下 from django.db import models class Publish(models.Mode ...

  7. 基于DRF的图书增删改查

    功能演示 信息展示 添加功能 编辑功能 删除功能 DRF构建后台数据 本例的Model如下 from django.db import models class Publish(models.Mode ...

  8. 使用轻量级ORM Dapper进行增删改查

      项目背景 前一段时间,开始做一个项目,在考虑数据访问层是考虑技术选型,考虑过原始的ADO.NET.微软的EF.NH等.再跟经理讨论后,经理强调不要用Ef,NH做ORM,后期的sql优化不好做,公司 ...

  9. Django之数据表增删改查

    Django数据增删改查: 上课代码 from django.shortcuts import render,HttpResponse # Create your views here. from a ...

随机推荐

  1. HTML+css基础 表格标签table Table标签属性 td标签属性

    表格标签table:   他是由行与列构成,最小单位是单元格. 行标签  <tr></tr> 单元格标签<td></td> Table标签属性: Bor ...

  2. GitHUB帐号申请及相关操作

    GitHUB帐号申请及相关操作 GitHub 是一个面向开源及私有软件项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub.GitHub 于 2008 年 4 月 10 ...

  3. 【More Effective C++ 条款1】仔细区别pointers和references

    1)操作符的差别 指针使用"*"和"->"操作符,而引用使用"."操作符 2)初始化的差别 有空指针,但是没有空引用,和const对象 ...

  4. 【java】Java多线程总结之线程安全队列Queue【转载】

    原文地址:https://www.cnblogs.com/java-jun-world2099/articles/10165949.html ============================= ...

  5. SUSE 中文是乱码

    http://www.wo81.com/tec/os/suse/2014-04-30/186.html   操作系统:SUSE Linux Enterprise 11 问题:vi 打开文件,中文是乱码 ...

  6. SQLServer之服务器连接

    目录 SQL Server Management Studio连接 CMD命令行窗口连接 通用数据连接文件连接 SQL Server Management Studio连接 定义 SQL Server ...

  7. php xdebug的配置、调试、跟踪、调优、分析

    xdebug 的 profiler 是一个强大的工具,它能分析 PHP 代码,探测瓶颈,或者通常意义上来说查看哪部分代码运行缓慢以及可以使用速度提升.Xdebug 2 分析器输出一种兼容 cacheg ...

  8. ALBERT+BiLSTM+CRF实现序列标注

    一.模型框架图 二.分层介绍 1)ALBERT层 albert是以单个汉字作为输入的(本次配置最大为128个,短句做padding),两边分别加上开始标识CLS和结束标识SEP,输出的是每个输入wor ...

  9. js点击按钮button效果(波效果)

    Material Design风格纯js按钮点击波特效 演示效果 html部分: <button data-ripple> Demo button 6 </button> cs ...

  10. cs1.6 人物地址查询

    打开游戏 控制台命令 增加一个BOT:bot_add 增加一个警察:bot_add_ct 增加一个匪徒:bot_add_t 让BOT站在原地不动:bot_stop 1 "-"减号: ...