ORM介绍
什么是ORM
对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。
ORM特点
在操作数据库的时候,不用在写原生SQL语句,相对而言,执行效率低了。
书写位置
在models.py文件中
对应关系
类名 >>> 表名
对象 >>> 记录
属性 >>> 字段
ORM创建表
1.在models.py中书写一个类
class User(models.Model): id = models.AutoField(primary_key=True) # 等价于id int primary_key auto_increment username = models.CharField(max_length=32) # 等价于username varchar(32) password = models.IntegerField() # 等价于password int
注意:由于一张表中必须要有一个主键字段 并且一般情况下都叫id字段
所以ORM当你不定义主键字段的时候会自动帮你创建一个名为id主键字段(如果是别的想用别的字段名就必须自己创建)
CharField必须要指定max_length参数 不指定会直接报错
2.执行数据库迁移命令
python3 manage.py makemigrations python3 manage.py migrate
注意:只要你修改了models.py中跟数据库相关的代码 就必须重新执行上述的两条命令
字段的增删改查
添加字段
添加字段可以在类体代码中直接添加即可。
class User(models.Model): id = models.AutoField(primary_key=True) # 等价于id int primary_key auto_increment username = models.CharField(max_length=32) # 等价于username varchar(32) password = models.IntegerField() # 等价于password int info = models.CharField(max_length=32)
但是如果数据表中已经有了数据,那么添加字段就需要解决原有记录的数据问题
解决方式:
1.在终端中输入默认值
2.设置该字段可以为空
info = models.CharField(max_length=32,null=True)
3.直接设置默认值
hobby = models.CharField(max_length=32,default='study')
字段的修改
直接修改代码然后执行数据库迁移的两条命令即可
字段的删除
直接注释对应的字段然后执行数据库迁移的两条命令即可
注意:执行完毕之后字段对应的数据也就都被删除了
数据的增删改查
为方便学习简单的建立一个HTML网页通过按钮实现增删改查的功能
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <h1 class="text-center">列表展示</h1> <a href="/add/" class="btn btn-success btn-lg">添加数据</a> <table class="table table-striped table-hover"> <thead> <tr> <th>ID</th> <th>UserName</th> <th>PassWord</th> <th>operate</th> </tr> </thead> <tbody> {% for user in user_list %} <tr> <td>{{ user.id }}</td> <td>{{ user.username }}</td> <td>{{ user.password }}</td> <td> <a href="/edit/?id={{ user.id }}" class="btn btn-primary">修改</a> <a href="/delete/?id={{ user.id }}" class="btn btn-danger">删除</a> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </body> </html>userlist.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="/static/css/bootstrap.min.css"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <h1 class="text-center">添加数据</h1> <form action="" method="post"> <div class="form-group"> username: <input type="text" name="username" class="form-control"> </div> <div class="form-group"> password:<input type="password" name="password" class="form-control"> </div> <input type="submit" value="提交" class="btn btn-success btn-block"> </form> </div> </div> </body> </html>add.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <h1 class="text-center">修改数据</h1> <form action="" method="post"> <div class="form-group"> username: <input type="text" name="username" class="form-control" value="{{ edit_obj.username }}"> </div> <div class="form-group"> password:<input type="password" name="password" class="form-control" value="{{ edit_obj.password }}"> </div> <input type="submit" value="提交" class="btn btn-success btn-block"> </form> </div> </div> </body> </html>edit.html
数据的增加
def add(request): # 判断请求方式 if request.method == 'POST': # 获取页面发送的数据 username = request.POST.get('username') password = request.POST.get('password') # 添加数据 models.User.objects.create(username=username, password=password) # 返回页面 return redirect('/index/') return render(request, 'add.html') # 第二种方式 user_obj = models.User(username=username,password=password) user_obj.save() # 保存数据
数据的查询
def show_list(request): # 查询所有 user_list = models.User.objects.all() return render(request, 'userlist.html', locals()) # 查询第一条 models.User.objects.filter(id=id).first() # filter相当于sql语句中的where,多个条件相当于用and连接
数据的修改
def edit(request): # 获取发送的id id = request.GET.get('id') # 根据id查询数据 edit_obj = models.User.objects.filter(id=id).first() if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 修改数据 models.User.objects.filter(id=id).update(username=username, password=password) return redirect('/index/') return render(request, 'edit.html', locals())
数据的删除
def delete(request): # 获取id id = request.GET.get('id') # 删除数据 models.User.objects.filter(id=id).delete() return redirect('/index/')
ORM创建表关系
以图书表,出版社表,作者表,作者详情表为例
一对多
# 创建表关系 先将基表创建出来 然后再添加外键字段 class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) # 总共八位 小数点后面占两位 """ 图书和出版社是一对多 并且书是多的一方 所以外键字段放在书表里面 """ publish = models.ForeignKey(to='Publish') # 默认就是与出版社表的主键字段做外键关联 """ 如果字段对应的是ForeignKey 那么会orm会自动在字段的后面加_id 如果你自作聪明的加了_id那么orm还是会在后面继续加_id 后面在定义ForeignKey的时候就不要自己加_id """
多对多
""" 图书和作者是多对多的关系 外键字段建在任意一方均可 但是推荐你建在查询频率较高的一方 """ authors = models.ManyToManyField(to='Author') """ authors是一个虚拟字段 主要是用来告诉orm 书籍表和作者表是多对多关系 让orm自动帮你创建第三张关系表 """
一对一
class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() """ 作者与作者详情是一对一的关系 外键字段建在任意一方都可以 但是推荐你建在查询频率较高的表中 """ author_detail = models.OneToOneField(to='AuthorDetail') """ OneToOneField也会自动给字段加_id后缀 所以你也不要自作聪明的自己加_id """ class AuthorDetail(models.Model): phone = models.BigIntegerField() # 或者直接字符类型 addr = models.CharField(max_length=32)