Redis效能測試
阿新 • • 發佈:2022-12-07
Django ORM
目錄orm不會建立庫,只能建立到表的層面。需要自己手動敲命令建立庫
1、建立模型表
ORM:"""物件關係對映""" 作用:能夠讓一個不會用sql語句的小白,也能通過python面向物件的程式碼簡單快捷的操作資料庫 不足之處:封裝成都太高,有時候sql效率偏低,需要自己寫sql語句 類 表 物件 記錄 物件屬性 記錄某個欄位對應的值
- 第一步:先去應用下的models.py中書寫一個模型類
# 應用下的models.py class User(models.Model): # id int primary key auto_increment id = models.AutoField(parmary_key=True) # username varchar(32) username = models.CharField(max_length=32) # passwrod int password = models.IntegerField() ************************************2.資料庫遷移命令************************************************** python manage.py makemigrations 將操作記錄記錄到小本本上(migrations資料夾) python manage.py migrate 將操作真正同步到資料庫中 ********************************************************************************************************
#應用下的modles.py from django.db import models # Create your models here. class User(models.Model): # id int primary key auto_increment id = models.AutoField(primary_key=True,verbose_name='主鍵') # username varchar(32) username = models.CharField(max_length=32, verbose_name='使用者名稱') """ CharField必須指定max_length引數,不指定會直接報錯 verhose_name該引數是所有欄位都有的,就是用來對欄位的解釋 """ # passwrod int password = models.IntegerField(verbose_name='密碼') class Author(models.Model): # 由於一張表中必須要有一個主鍵欄位,並且一般情況下都叫id欄位 # 所以orm當不定義主鍵欄位的時候,orm會自動建立一個名為id欄位 # 也就意味著後續再建立模型表的時候,如果主鍵欄位名沒有額外的叫法,那麼主鍵欄位可以省略不寫 username = models.CharField(max_length=32) password = models.IntegerField()
- 第二步:資料庫遷移命令
python manage.py makemigrations #⽣成資料庫遷移⽂件
應用資料夾下的migrations資料夾下多了一個0001._initial.py日誌檔案
python manage.py migrate #⽣成資料庫表
#將操作真正同步到資料庫中
資料庫遷移的兩條命令輸入完成後,此時資料庫中會出現很多張表
一個Djanog專案可以有多個應用,那麼多個應用之間可能會出現表名衝突的情況,那麼加上字首就可以完全避免衝突
"""
只要修改了models.py中跟資料庫相關的程式碼,就必須重新執行資料遷移的兩條命令
"""
2、欄位的增刪改查
2. 1、 欄位的增加
"""
1.可以在終端內直接給出預設值
age=models.IntegerField(verbose_name='年齡')
2.該欄位可以為空
info = models.CharField(max_length=32,verbose_name='資訊', null=True)
3.直接給欄位設定預設值
hobby = models.CharField(max_length=32,verbose_name='愛好', default='play')
"""
終端內直接給預設值操作如下圖
切記,只要動了資料庫相關的程式碼就必須執行資料庫遷移的兩條命令
******************************************************************
python manage.py makemigrations
python manage.py migrate
******************************************************************
2. 2、欄位的修改
"""直接修改程式碼然後執行資料庫遷移的兩條命令即可"""
2. 3、欄位的刪除
直接註釋掉對應的欄位程式碼,然後執行資料遷移的兩條命令即可
執行完畢後,欄位對應的資料都沒有了
"""
在操作models.py時,一定要細心
執行遷移命令之前一定要檢查一下程式碼
"""
3、資料的增刪改查
3. 1、 查資料
#views.py
def userlist(request):
# 查詢出user使用者表裡的所有資料.
# 方式一
# data = models.User.objects.filter()
# print(data)
# 方式二:
user_queryset = models.User.objects.all()
return render(request, 'userlist.html', locals())
# views.py
from app02 import models
#res=models.User.objects.filter(username=username)
# user_obj=res[0]
"""
返回值先看成是一個列表套資料物件的格式
也支援索引取值,切片操作,但是不支援負數索引
同樣也不推薦使用索引方式取值
"""
# 下面這條程式碼等價於 select * from user where username='zhao';
user_obj=models.User.objects.filter(username=username).first()
print(user_obj)
print(user_obj.username)
print(user_obj.password)
filter括號內可以攜帶多個引數,引數與引數之間預設是and關係
可以把filter聯想成MySQL中的where
user_obj=models.User.objects.filter(username=username,password=password).first()
#select * from user where username='zhao' and password=132;
登入功能
# views.py
def login(request):
if request.method == 'POST':
# 獲取使用者的使用者名稱和密碼,然後利用orm操作資料庫,校驗資料是否正確
username = request.POST.get('username')
password = request.POST.get('password')
# 去資料庫中查詢資料
from app02 import models
# select * from user where username='zhao';
user_obj = models.User.objects.filter(username=username).first()
# < QuerySet[ < User: Userobject(1) >] > [資料物件1,資料物件2......]
# print(res)
# user_obj=res[0]
# print(user_obj)
# print(user_obj.username)
# print(user_obj.password)
if user_obj:
# 比對密碼是否一致
if password == user_obj.password:
return HttpResponse('登入成功')
else:
return HttpResponse('密碼錯誤')
else:
return HttpResponse('使用者不存在')
return render(request, 'login.html')
3. 2 、增加資料
#第一種方法 create()
from app02 import models
res = models.User.objects.create(username=username, password=password)
# 返回值就是當前被建立的物件本身
print(res, res.username, res.password)
# 第二種方法 物件.save()
from app02 import models
#生成一個類物件
user_obj = models.User(username=username, password=password)
#物件呼叫save方法
user_obj.save()#儲存資料
註冊功能
# views.py
def register(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
# 直接獲取使用者資料存入資料庫
from app02 import models
res = models.User.objects.create(username=username, password=password)
# 返回值就是當前被建立的物件本身
print(res, res.username, res.password)
# 先給使用者返回已給註冊頁面
return render(request, 'register.html')
3. 3 、修改資料
# 修改資料方式一
# 獲取到使用者想要刪除 的資料id值
delete_id = request.GET('user_id')
models.User.objects.filter(id=edit_id).update(username=username, password=password)
"""
將filter查詢出來的列表中所有物件全部更新 批量更新
只修改被修改的欄位
"""
# 修改資料方式二
edit_obj = models.User.objects.filter(id=edit_id).first()
edit_obj.username = username
edit_obj.password = password
edit_obj.save()
"""
方式二當欄位特別多的時候效率很低
從頭到尾將資料的所有欄位全部更新一遍,無論該欄位是否被修改
"""
3. 4、 刪除資料
# 刪除使用者
def delete_user(request):
# 獲取到使用者想要刪除 的資料id值
delete_id = request.GET('user_id')
# 直接去資料庫找到對應的資料刪除即可
models.User.objects.filter(id=delete_id).delete()
"""
批量刪除
"""
#跳轉到展示頁面
return redirect('/userlist/')
真正刪除資料是要有二次確認的,
刪除資料內部其實不是真正的刪除,我們會給資料新增一個標識欄位用來標識當前資料是否被刪除,如果刪除了,僅僅是將一個欄位修改了一個狀態
3.5、示例:
#先將資料庫中的資料全部展示到前端,然後給一個數據兩個按鈕,一個編輯,一個刪除
#編輯功能
#點選編輯按鈕,朝後端傳送編輯資料的請求
"""如何告訴後端使用者想要編輯哪條資料?
將編輯按鈕所在的那一行資料的主鍵值傳送給後端
利用url問號後面攜帶引數的方式
"""
#後端查詢出使用者想要編輯的資料物件,展示到前端頁面,供使用者檢視和編輯
#刪除功能
將資料從前端頁面刪除
- 資料展示到前端頁面
<!-- userlist.html--->
<h2 class="text-center">資料展示</h2>
<div class="container">
<div class="row">
<div class="col-md-8 col-offset-2">
<table class="table table-striped table-hover ">
<thead>
<tr>
<th>ID</th>
<th>username</th>
<th>password</th>
<th class="text-center">action</th>
</tr>
</thead>
<tbody>
{% for user_obj in user_queryset %}
<tr>
<td>{{ user_obj.id }}</td>
<td>{{ user_obj.username }}</td>
<td>{{ user_obj.password }}</td>
<td class="text-center">
<a href="/edit_user/?user_id={{ user_obj.id }}" class="btn btn-primary btn-xs">編輯</a>
<a href="/delete_user/user_id={{ user_obj.id }}" class="btn btn-danger btn-xs">刪除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
# views.py
# 展示使用者列表
def userlist(request):
# 查詢出user使用者表裡的所有資料.
# 方式一
# data = models.User.objects.filter()
# print(data)
# 方式二:
user_queryset = models.User.objects.all()
return render(request, 'userlist.html', locals())
- 編輯使用者資料
<!-- edit_user.html--->
<h1 class="text-center">編輯</h1>
<div class="container">
<div class="row">
<div class="col-md-offset-2 col-md-8">
<form action="" method="post">
<p>username:<input type="text" name="username" class="form-control" value="{{ edit_obj.username }}"></p>
<p>password:<input type="password" name="password" class="form-control" value="{{ edit_obj.password }}"></p>
<input type="submit" class="btn btn-info btn-block" value="編輯">
</form>
</div>
</div>
</div>
#views.py
from app03 import models
def edit_user(request):
# 獲取url問號後面的引數
edit_id = request.GET.get('user_id')
# 查詢當前使用者想要編輯的資料物件
edit_obj = models.User.objects.filter(id=edit_id).first()
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
# 去資料庫中修改對應的資料內容
# 修改資料方式一
# models.User.objects.filter(id=edit_id).update(username=username, password=password)
"""
將filter查詢出來的列表中所有物件全部更新 批量更新
只修改被修改的欄位
"""
# 修改資料方式二
edit_obj.username = username
edit_obj.password = password
edit_obj.save()
"""
方式二當欄位特別多的時候效率很低
從頭到尾將資料的所有欄位全部更新一遍,無論該欄位是否被修改
"""
# 跳轉到資料的展示頁面
return redirect('/userlist/')
# 將資料展示到頁面上
return render(request, 'edit_user.html', locals())
- 刪除資料
<!-- userlist.html--->
<a href="/delete_user/user_id={{ user_obj.id }}" class="btn btn-danger btn-xs">刪除</a>
#views.py
# 刪除使用者
def delete_user(request):
# 獲取到使用者想要刪除 的資料id值
delete_id = request.GET.get('user_id')
# 直接去資料庫找到對應的資料刪除即可
models.User.objects.filter(id=delete_id).delete()
"""
批量刪除
"""
#跳轉到展示頁面
return redirect('/userlist/')
4、orm中建立表關係(外來鍵)
"""
表與表關係
一對多
models.ForeignKey(to='Publish', on_delete=models.CASCADE)
多對多
models.ManyToManyField(to='Author')
一對一
models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)
判斷表關係方式:換位思考
"""
# 建立表關係, 先將基表創建出來,然後在新增外來鍵欄位
class Book(models.Model):
title = models.CharField(max_length=32, verbose_name='書名')
price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='價格')
# 小數總共8位,小數點後佔2位
"""
圖書和出版社是一對多,並且書是多的一方,所以外來鍵欄位放在書表裡面
"""
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE) # 預設就是與出版社表的主鍵欄位做外來鍵關聯
"""
如果欄位對應的是ForeignKey,那麼orm會自動在欄位的後面加_id
如果自己手動的加了_id,那麼orm還是會在後面加_id
"""
"""
圖書 和作者 是多對多的關係,外來鍵欄位建在任意一方即可,推薦建在查詢頻率較高的一方,
"""
authors = models.ManyToManyField(to='Author')
"""
authors是一個虛擬欄位,主要是用來告訴orm,書籍表與作者表是多對多的關係
讓orm自動建立第三章關係表
"""
class Publish(models.Model):
name = models.CharField(max_length=32, verbose_name='出版社')
addr = models.CharField(max_length=32, verbose_name='地址')
class Author(models.Model):
name = models.CharField(max_length=32, verbose_name='作者名')
age = models.IntegerField(verbose_name='年齡')
"""
作者與作者詳情是一對一的關係,外來鍵欄位建立在任意放一方都可以,但是建議建立在查詢頻率較高的地方
"""
author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE) # 級聯刪除
"""
OneToOneFiel也會自動給欄位加_id字尾,不需要自己加
"""
class AuthorDetail(models.Model):
phone = models.BigIntegerField(verbose_name='電話')
addr = models.CharField(max_length=32, verbose_name='作者地址')
"""
orm中如何定義表關係
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author')
ForeignKey與OneToOneField會自動在欄位後面加_id字尾
"""
5、多對多關係的三種建立方式
- 全自動
#全自動:利用orm自動幫我們建立第三張關係表
class Book(models.Model):
name=models.CharField(max_length=32)
authors=models.ManyToManyField(to='Author')
class Author(models.Model):
name=models.CharField(max_length=32)
"""
優點:程式碼不需要自己寫,還支援orm提供的第三張關係表的方法:(add,remove,clear,set)
缺點:第三張關係表擴充套件性極差,(不能額外的新增欄位)
"""
- 純手動
class Book(models.Model):
name=models.CharField(max_length=32)
class Author(models.Model):
name=models.CharField(max_length=32)
class BookToAuthor(models.Model):
book=models.ForeignKey(to='Book',on_delete=models.CASCADE)
author=models.ForeignKey(to='Author',on_delete=models.CASCADE)
"""
優點:第三張關係表完全取決於自己進行額外的拓展
缺點:需要寫程式碼較多,不能使用orm提供的簡單方法:(add,remove,clear)
不建議使用該方式
"""
- 半自動
class Book(models.Model):
name = models.CharField(max_length=32)
authors = models.ManyToManyField(to='Author',
through='BookToAuthor',
through_fields=('book', 'author')
)
class Author(models.Model):
name = models.CharField(max_length=32)
class BookToAuthor(models.Model):
book = models.ForeignKey(to='Book', on_delete=models.CASCADE)
author = models.ForeignKey(to='Author', on_delete=models.CASCADE)
"""through_fields欄位先後順序:
第三張表查詢對應的表,需要用到哪個欄位就把哪個欄位放前面,
也就是說,當前表是誰,就把對應的關聯欄位放前面
半自動可以使用orm的正反向查詢,但是沒有辦法使用add,remove,clear,set這四個方法
"""
# 總結:
只需要掌握全自動和半自動,半自動擴充套件性高,一般都採用半自動,