一、添加表記錄
# 方式一:
book=Book(title="GO",price="99",pub_date="2018-12-31",publish="人民出版社")
book.save()
print(book.nid) # 傳回值就是 Book 生成的對象
# 方式二:
# 注意:create 方法的傳回目前生成的表記錄對象
book = Book.objects.create(title="GO",price="99",pub_date="2018-12-31",publish="人民出版社")
注:關于create和save方法2種方式的不同,具體詳見原文連結:
https://blog.csdn.net/weixin_42134789/article/details/80203270
深入了解Django建立對象的create和save方法:
Django的模型(Model)的本質是類,并不是一個具體的對象(Object)。當你設計好模型後,你就可以對Model進行執行個體化進而建立一個一個具體的對象。Django對于建立對象提供了2種不同的save與create方法,我們來仔細分析下這兩種方式有什麼不同。
用save方法建立對象
用save方法建立一個名叫john的具體對象,我們可以這麼做。記住你隻有用了save()方法後,Django才會将這個對象的資訊存儲到資料庫中。
用create方法建立對象
正因為用save方法建立對象有2步,而且程式設計人員容易忘記加上save(),Django提供了一個更便捷的create方法,如下。如果你使用create方法,無需再加上save()。create方法不僅建立了新的對象,而且直接将資訊存儲到資料庫裡。
save與create方法比較:
create隻能用于建立新的對象,在資料庫層總是執行insert的操作。save不僅用于建立新的對象,也能用于更新對象的現有資料,在資料庫層總是先執行update,找不到具體對象後再執行insert的操作。對于建立全新的對象,兩者都可以。如果更新已有對象資訊,隻能用save()方法。
User自帶的create_user方法
如果你要Auth自帶的User模型建立新對象,你需要使用create_user方法,而不是create方法,如下所示。create_user方法很有用,自動會給密碼加Hash。
————————————————
版權聲明:本文為CSDN部落客「大江狗」的原創文章,遵循 CC 4.0 BY-SA 版權協定,轉載請附上原文出處連結及本聲明。
原文連結:https://blog.csdn.net/weixin_42134789/article/details/80203270
二 、查詢表記錄
1、查詢API:
all(): | 查詢所有結果 |
filter(**kwargs): | 包含了與所給篩選條件相比對的對象 |
get(**kwargs): | 傳回與所給篩選條件相比對的對象,傳回結果有且隻有一個 |
exclude(**kwargs): | 包含了與所給篩選條件不比對的對象 |
order_by(*field): | 對查詢結果排序 |
reverse(): | 對查詢結果反向排序 |
order_by(*field): | 對查詢結果排序 |
count(): | 傳回資料庫中比對查詢(QuerySet)的對象數量。 |
first(): | 傳回第一條記錄 |
last(): | 傳回最後一條記錄 |
exists(): | 如果QuerySet包含資料,就傳回True,否則傳回False |
distinct(): | 從傳回結果中剔除重複記錄 |
"""以下示範單表查詢的代碼"""
# 1、all(): 查詢所有結果 傳回值是 queryset
ret = Book.objects.all()
print(ret) # <QuerySet [<Book: Book object (22)>, <Book: Book object (23)>, <Book: Book object (24)>, <Book: Book object (25)>]>
# 2、filter(): 查詢包含了與所給篩選條件相比對的對象
ret = Book.objects.filter(title="JAVA",price="88") # 多條件查詢 當一個條件不滿足時,顯示為空- “且”的關系。<QuerySet []>
print(ret) # <QuerySet [<Book: Book object (23)>]>
# 3、get(): # 查詢結果有且隻有一個才執行。
ret = Book.objects.get(price="88") # 報錯:get() returned more than one Book -- it returned 3! 如果符合篩選條件的對象超過一個或者沒有都會抛出錯誤。
ret = Book.objects.get(title="JAVA") # get() 傳回與所給篩選條件相比對的對象,傳回結果有且隻有一個
print(ret.title) # JAVA
# 4、first() last() # 傳回第一條記錄 model對象
ret = Book.objects.all()[0]
ret = Book.objects.all().first()
ret = Book.objects.all().last()
# 5、exclude() # 傳回值是 queryset
ret = Book.objects.exclude(price=88)
print(ret) # <QuerySet [<Book: Book object (25)>]>
# 6、order_by # 排序,傳回值是 queryset
ret = Book.objects.all().order_by("price") # 按價格升序
ret = Book.objects.all().order_by("-price") # 按價格降序
# 7、count() # 計數,傳回資料庫中比對查詢(QuerySet)的對象數量。傳回值是 int 類型
ret = Book.objects.all().count()
print(ret) # 4
# 8、reverse() # 對查詢結果反向排序
Book.objects.all().order_by("price").reverse()
# 9、exists() # 邏輯判斷!如果QuerySet包含資料,就傳回True,否則傳回False
is_exist = Book.objects.all().exists() # b'SELECT (1) AS `a` FROM `app01_book` LIMIT 1'; args=()
if is_exist:
print("OK")
# ------------------------------------------------------------------------------------------------
# 重點!!
# 10、values() # 傳回值是 queryset
ret = Book.objects.all().values("title","price") # 傳回一個ValueQuerySet——一個特殊的QuerySet 清單套字典 [{...}]
print(ret) # <QuerySet [{'title': 'python', 'price': Decimal('99.00')}, {'title': 'JAVA', 'price': Decimal('88.00')}, {'title': 'JavaScript', 'price': Decimal('88.00')}, {'title': 'GO', 'price': Decimal('66.00')}]>
# 11、values_list() # 傳回值是 queryset
# 12、distinct() # 從傳回結果中剔除重複記錄,傳回值是 queryset
ret = Book.objects.all().distinct() # 針對這種 all()再調用 distinct 沒有意義,因為對象包含了主鍵 nid,不可能重複!
ret = Book.objects.all().values("title").distinct() # 總共5本書,去重後結果是4本。配合比對 values 去重功能才會顯現
print(ret) # <QuerySet [{'title': 'python'}, {'title': 'JAVA'}, {'title': 'JavaScript'}, {'title': 'GO'}]>
2、基于雙下劃線的模糊查詢:
"""查詢價格"""
ret = Book.objects.filter(price__in=[88,99]).values("price")
# 查詢價格區間在 88~99 的書籍
ret = Book.objects.filter(price__lt=100).values("price")
# 查詢價格小于等于 100 的書籍
ret = Book.objects.filter(price__gt=100).values("price")
# 查詢價格大于等于 100 的書籍
ret = Book.objects.filter(price__gte=80).values("price")
# 查詢價格大于等于 88 的書籍
"""查詢名稱以 “J” 開頭的"""
ret = Book.objects.filter(title__startswith="J").values("title")
# 查詢結果區分大小寫
ret = Book.objects.filter(title__istartswith="j").values("title")
# 查詢結果不區分大小寫
ret = Book.objects.filter(title__contains="S").values("title")
# 查詢結果隻要包含S的,區分大小寫
ret = Book.objects.filter(title__icontains="S").values("title")
# 查詢結果不區分大小寫
"""查詢時間:2018年釋出的"""
ret = Book.objects.filter(pub_date__year=2018).values("title")
# 僅查詢釋出年份
ret = Book.objects.filter(pub_date__year=2018,pub_date__month=10).values("title")
# 查詢2018年10月釋出的
print(ret)
# <QuerySet []> 輸出為空的原因:遇到時間偏差,因為時間子產品出問題,需要到 settings.py 中修改 :USE_TZ = True 改為 False
# <QuerySet [{'title': 'C++'}]> 這是修改以後的輸出,問題解決!
注意:
最後查詢年月列印輸出為空的原因:遇到時間偏差,因為時間子產品出問題,需要到 settings.py 中修改 :USE_TZ = True 改為 False
<QuerySet [{‘title’: ‘C++’}]> 這是修改以後的輸出,問題解決。
三、删除表記錄
删除方法就是 delete()。它運作時立即删除對象而不傳回任何值。例如:
也可以一次性删除多個對象。每個 QuerySet 都有一個 delete() 方法,它一次性删除 QuerySet 中所有的對象。
示例:下面的代碼将删除 book_price 是 123 的 Book 對象:
# 以下2種寫法都可以
Book.objects.filter(price=123).delete()
Book.objects.filter(price=delete_book_price).delete()
四、修改表記錄
update()方法對于任何結果集(QuerySet)均有效,這意味着你可以同時更新多條記錄update()方法會傳回一個整型數值,表示受影響的記錄條數。
其實以上隻單純示範文法,它需要在浏覽器中輸入對應的值才能執行操作。相信沒有人願意這樣做。在下面的案例練習中會結合HTML頁面按鈕,來實作增、删、改、查的操作。
練習:圖書管理系統
urls.py:
from django.contrib import admin
from django.urls import path, re_path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('books/', views.books, name="books"),
path('books/add/', views.addbook),
# re_path('books/delete/(\d+)', views.delbook, name="books"), # 這裡僅用于删除!
re_path('books/delete/(\d+)', views.delbook), # name="books"是唯一的,就不能再用了!
re_path('books/edit/(\d+)', views.editbook),
]
app01\views.py:
from django.shortcuts import render,HttpResponse,redirect
from app01.models import Book
from django.urls import reverse
def addbook(request):
"""添加功能"""
if request.method == "POST":
# 擷取使用者送出的資料
print(request.POST)
# ---------------------------------------------------------------------------------------
# 方式 1 :逐個取主鍵來建立資料,比較麻煩,特别是資料量大的情況下。
title = request.POST.get("title")
price = request.POST.get("price")
pub_date = request.POST.get("pub_date")
publish = request.POST.get("publish")
book = Book.objects.create(title=title,price=price,pub_date=pub_date,publish=publish)
# ---------------------------------------------------------------------------------------
# 方式 2 :先轉成字典,再進行添加操作,相對于上面的方式1,友善許多!但是不直覺!
# data = request.POST.dict()
# del data["csrfmiddlewaretoken"]
# book = Book.objects.create(**data)
# ---------------------------------------------------------------------------------------
return redirect(reverse("books"))
else:
return render(request,"addbook.html")
def books(request):
"""查詢功能"""
book_list = Book.objects.all() # 查所有
# print(book_list) # [obj1, obj2, obj3...]
# print(book_list[0].title)
return render(request,"books.html",{"book_list":book_list})
def delbook(request,delete_book_id):
"""删除功能"""
Book.objects.filter(nid=delete_book_id).delete()
return redirect(reverse("books"))
def editbook(request,edit_book_id):
"""修改功能"""
# 以下2行代碼隻是示範了2種功能,查詢與編輯同時進行
# Book.objects.filter(nid=edit_book_id).update(price=88,title="Django") # 隻要輸入符合的ID,都會修改為:price=88,title="Django"
# Book.objects.filter(price=88).update(publish="工業出版社") # 隻要輸入符合的 price,都會修改為:publish="工業出版社"
if request.method == "GET": # GET請求
edit_book = Book.objects.filter(nid=edit_book_id)[0]
return render(request, "editbook.html",{"edit_book":edit_book})
else: # POST請求
title = request.POST.get("title")
price = request.POST.get("price")
pub_date = request.POST.get("pub_date")
publish = request.POST.get("publish")
Book.objects.filter(nid=edit_book_id).update(title=title, price=price, pub_date=pub_date, publish=publish)
return redirect("/books/")
models.py:
from django.db import models
# 存放表結構
class Book(models.Model):
nid = models.AutoField(primary_key=True) #自動遞增主鍵
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8, decimal_places=2) #999999.99
pub_date = models.DateTimeField() #"2019-10-01"
publish = models.CharField(max_length=32)