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>
说明:
#查询所有的书籍 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>
删除图书
在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 %}