Django的ORM單表操作
阿新 • • 發佈:2022-02-25
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_incrementusername = 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)