Django與數據庫交互的實現
1 如何創建項目數據庫
首先,在虛擬機數據庫中建立一個與項目同名的數據庫,方便管理。
(django_test) bd@DF:~$ mysql -u admin -p
輸入密碼,進入數據庫後。
mysql> SHOW DATABASES;
查看當前所有已有的數據庫,然後創建數據庫。
mysql> CREATE DATABASE 'django_test';
就會有一個名為‘django_test’的數據庫。
+--------------------+ | Database | +--------------------+ | information_schema | | django_test | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.10 sec)
2 進行數據庫與django的交互
有瞭數據庫之後,我們需要把這個庫配置到項目中,進行關系綁定。
首先在settings.py文件中的DATABASES一項:
DATABASES = { 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 'ENGINE': 'django.db.backends.mysql', # 數據庫引擎 'NAME': 'django_test', # 哪一個數據庫 'USER': 'admin', # 用戶 'PASSWORD': 'yourpassword', # 數據庫密碼 'HOST': '127.0.0.1', # 數據庫服務器IP 'PORT': '3306' # 數據庫端口(需要去ubuntu中設置端口轉發,虛擬機的端口是3306,我們直接轉發到本地3306) } }
將默認的配置註釋掉,然後帶上自己的數據庫信息.端口轉發(ubuntu):
由於需要操作mysql數據庫,所以需要在虛擬環境中安裝pymysql,註意:需要一定要在對應的虛擬環境中安裝。
pip install mysql -i https://pypi.douban.com/simple
使用豆瓣源會快一些。然後pip list 查看自己是否已經有pymysql。有瞭之後,進入項目總目錄下的__init__.py文件。
import pymysql pymysql.install_as_MySQLdb()
添加兩行代碼,完成映射的導入。然後去我們需要進行數據庫交互的app中的models.py.
from django.db import models # Create your models here. class User(models.Model): # id = models.AutoField(primary_key=True) # 主鍵字段不需要我們自己寫 name = models.CharField(max_length=30) age = models.IntegerField(null=True) sex = models.IntegerField(null=True) city = models.CharField(max_length=30, null=True) note = models.TextField(null=True) create_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True)
這裡我們定義瞭很多項,然後對應的數據類型是需要註意的(根據你定義的項的數據類型來),括號裡面的限定信息也需要註意。數據類型:
類型 | 說明 |
---|---|
AutoField | 自動增長的IntegerField,通常不用指定,不指定時Django會自動創建屬性名為id的自動增長屬性 |
BooleanField | 佈爾字段,值為True或False |
NullBooleanField | 支持Null、True、False三種值 |
CharField | 字符串,參數max_length表示最大字符個數 |
TextField | 大文本字段,一般超過4000個字符時使用 |
IntegerField | 整數 |
DecimalField | 十進制浮點數, 參數max_digits表示總位數, 參數decimal_places表示小數位數 |
FloatField | 浮點數 |
DateField | 日期, 參數auto_now表示每次保存對象時,自動設置該字段為當前時間,用於”最後一次修改”的時間戳,它總是使用當前日期,默認為False; 參數auto_now_add表示當對象第一次被創建時自動設置當前時間,用於創建的時間戳,它總是使用當前日期,默認為False; 參數auto_now_add和auto_now是相互排斥的,組合將會發生錯誤 |
TimeField | 時間,參數同DateField |
DateTimeField | 日期時間,參數同DateField |
FileField | 上傳文件字段 |
ImageField | 繼承於FileField,對上傳的內容進行校驗,確保是有效的圖片 |
限定條件:
選項 | 說明 |
---|---|
null | 如果為True,表示允許為空,默認值是False |
blank | 如果為True,則該字段允許為空白,默認值是False |
db_column | 字段的名稱,如果未指定,則使用屬性的名稱 |
db_index | 若值為True, 則在表中會為此字段創建索引,默認值是False |
default | 默認值 |
primary_key | 若為True,則該字段會成為模型的主鍵字段,默認值是False,一般作為AutoField的選項使用 |
unique | 如果為True, 這個字段在表中必須有唯一值,默認值是False |
max_length | 字段長度限制 |
DateField.auto_now | 修改數據時,更新時間,使用save方法才會有用 |
DateField.auto_now_add | 第一次添加會將當前時間設置進去,修改不會 |
在完成數據的導入之後,我們就要在虛擬機中進行遷移。移動到項目目錄下。
python manage.py makemigrations
命令後面可以跟app名稱,指定對某個app的模型進行映射,如果沒有寫,就所有的app都回去創建映射文件。再次之前,你必須保證你的app都在settings裡面註冊瞭。
在遷移完之後,我們需要將遷移的數據提交給數據庫(在虛擬機中且在目錄下):
python manage.py migrate
我們可以這樣理解,遷移是將我們在user類中定義的數據項轉化為create table這樣的mysql語句,然後就是將語句提交到數據庫中創建表。
創建完成後,我們在數據庫中查看是否完成操作:
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | django_test | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.00 sec) mysql> use django_test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +-----------------------+ | Tables_in_django_test | +-----------------------+ | django_migrations | | six_user | +-----------------------+ 2 rows in set (0.00 sec) mysql> describe six_user; +-------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(30) | NO | | NULL | | | age | int(11) | YES | | NULL | | | sex | int(11) | YES | | NULL | | | note | longtext | YES | | NULL | | | create_time | datetime(6) | NO | | NULL | | | update_time | datetime(6) | NO | | NULL | | | city | varchar(30) | YES | | NULL | | +-------------+-------------+------+-----+---------+----------------+ 8 rows in set (0.00 sec)
這裡我們首先show databases;查看庫,再進入我們的項目數據庫,選擇six_user查看表格。完成實現數據表創建操作。
如果我們需要修改表,那麼我們隻需要修改模型類就可以瞭,如果我們需要在模型類中添加一個字段,那麼我們不能直接增加,因為增加一個不可為空的字段會存在一個邏輯錯誤。即添加一個本身為空(添加進去的時候是空的)的不可為空字段是不被允許的,所以我們需要在括號中添加null=True。
如上面模型類的city字段,添加完成後,進行遷移和提交即可,就是上面兩個步驟,刪除也是一樣的,也就是說,隻要是更新模型類,都需要上面2個步驟。
3 添加數據
如果我們需要添加數據,我們試一下
from django.http import HttpResponse, HttpResponseNotFound from django.shortcuts import redirect, render from .models import User # Create your views here. def add_user(request): # 方法一 # user = User(name='zjj', age=18) # user.save() # 使用save方法保存提交數據 # return HttpResponse('添加成功') # 方法二 # user = User() # user.name = 'zj' # user.age = 18 # user.save() # return HttpResponse('添加成功') # 方法三 # User.objects.create(name='z', age=8) # return HttpResponse('添加成功') # 方法四 get_or_create會判斷有沒有傳入的數據(指完全一致的數據),如果有則不創建,隻獲取,如果沒有則創建,並獲取,返回一個元組。 user, flag = User.objects.get_or_create(name='z1', age=10) message = '添加成功' if not flag: message = '已有數據' print(user.name, user.create_time) return HttpResponse(message)
這裡我們首先需要引入models類中我們定義的User類,然後通過對User類實例化進行添加,以上舉例瞭四種方法,前兩種方法都需要使用save方法,後面兩種是調用對象的方法直接添加數據,較為方便,這裡需要講一下最後一個方法,這個方法會判斷傳入數據,如果沒有傳入數據,就會首先創建,然後獲取該數據,返回一個True,這裡我在上面print瞭幾條數據,可以去測試一下。如果是重復數據,就會不創建,返回數據,加一個False。那麼我們在這裡進行一個拆包,獲取兩個參數,然後做一個判斷,這樣就可以進行頁面的信息傳遞。
mysql> SELECT * FROM `six_user`; +----+------+------+------+------+----------------------------+----------------------------+------+ | id | name | age | sex | note | create_time | update_time | city | +----+------+------+------+------+----------------------------+----------------------------+------+ | 1 | zjj | 18 | NULL | NULL | 2021-03-10 21:40:18.246543 | 2021-03-10 21:40:18.246564 | NULL | | 2 | zj | 18 | NULL | NULL | 2021-03-10 21:44:36.590347 | 2021-03-10 21:44:36.590365 | NULL | | 3 | z | 8 | NULL | NULL | 2021-03-10 21:46:37.315176 | 2021-03-10 21:46:37.315195 | NULL | | 4 | z1 | 10 | NULL | NULL | 2021-03-10 21:56:20.559386 | 2021-03-10 21:56:20.559421 | NULL | +----+------+------+------+------+----------------------------+----------------------------+------+ 4 rows in set (0.00 sec)
然後還有一種方法就是在前端頁面添加數據,然後後端接收後添加入數據庫。
第一步,在路由中添加接收信息:
from django.contrib import admin from django.urls import path from . import views urlpatterns = [ path(r'add_user/<name>/<age>', views.add_user) ]
視圖函數中:
def add_user(request, name, age): user, flag = User.objects.get_or_create(name=name, age=age) message = '添加成功' if not flag: message = '已有數據' print(user.name, user.create_time) return HttpResponse(message)
這樣我們就可以在前端接收數據後,直接添加入數據庫
mysql> SELECT * FROM `six_user`; +----+------+------+------+------+----------------------------+----------------------------+------+ | id | name | age | sex | note | create_time | update_time | city | +----+------+------+------+------+----------------------------+----------------------------+------+ | 1 | zjj | 18 | NULL | NULL | 2021-03-10 21:40:18.246543 | 2021-03-10 21:40:18.246564 | NULL | | 2 | zj | 18 | NULL | NULL | 2021-03-10 21:44:36.590347 | 2021-03-10 21:44:36.590365 | NULL | | 3 | z | 8 | NULL | NULL | 2021-03-10 21:46:37.315176 | 2021-03-10 21:46:37.315195 | NULL | | 4 | z1 | 10 | NULL | NULL | 2021-03-10 21:56:20.559386 | 2021-03-10 21:56:20.559421 | NULL | | 5 | zjjj | 21 | NULL | NULL | 2021-03-10 22:06:47.200072 | 2021-03-10 22:06:47.200101 | NULL | +----+------+------+------+------+----------------------------+----------------------------+------+ 5 rows in set (0.00 sec)
4 查找數據
4.1查找所有數據
查找數據方法,我們先定一個函數來試試看:
def find_user(request): # 查詢所有數據 user_list = User.objects.all() print(user_list) return HttpResponse('查詢成功')
記得添加路由,然後我們在模型類下使用魔法方法修改print方法
def __str__(self): return 'id=%s, name=%s, age=%s, city=%s, note=%s' % (self.id, self.name, self.age, self.city, self.note)
那麼我們在print數據時可以看的清楚一些。
上面是查詢所有數據。那麼如何查詢一個數據呢?
4.2查詢一個數據
def find_user(request): # 查詢一個數據 user = User.objects.get(id=1) print(user, type(user)) return HttpResponse('查詢成功')
這裡需要註意的是,get方法是用來查詢唯一數據,如果你輸入的條件不是唯一的,會直接報錯。那麼查詢多個數據?
4.3查詢多條數據
def find_user(request): # 查詢多條數據 user_list = User.objects.filter(name=18) print(user_list, type(user_list)) return HttpResponse('查詢成功')
這裡我們使用filter方法
這裡返回的是一個集合對象(可迭代對象,即可被for循環)。
def find_user(request): # 查詢多條數據 user_list = User.objects.filter(age=18) for user in user_list: print(user) # print(user_list, type(user_list)) return HttpResponse('查詢成功')
這樣就能返回多條信息。
不僅如此,該對象還可以切片。
def find_user(request): # 查詢多條數據 user_list = User.objects.filter(age=18) # for user in user_list: # print(user) # print(user_list, type(user_list)) print(user_list[0:1]) return HttpResponse('查詢成功')
還可以轉型
def find_user(request): # 查詢多條數據 user_list = User.objects.filter(age=18) # for user in user_list: # print(user) # print(user_list, type(user_list)) # print(user_list[0:1]) print(list(user_list)) return HttpResponse('查詢成功')
4 更新數據
更新數據的步驟就是先獲得到你要修改的數據,然後對其進行重新賦值
4.1獲取數據
from django.shortcuts import render from django.http import HttpResponse from six.models import User from django.db.models import Count, Avg, Min, Max, Sum, F, Q # Create your views here. # 常用的查詢方法 def find(request): # 獲取所有數據 rs = User.objects.all() # 獲取第一條數據 rs = User.objects.first() # 獲取最後一條方法 rs = User.objects.last() # 獲取指定條件的多條數據 rs = User.objects.filter(age=18) # 獲取唯一的一條數據,一般的get返回對象具有唯一性(一般用id來查),如果有多個就會報錯,可以用try來處理 rs = User.objects.get(id=3)
這裡的方法很多,可根據需要來
4.2對數據排序
# 對結果排序 rs = User.objects.order_by('age') # 正序,從小到大 rs = User.objects.order_by('-age') # 倒序,從大到小 # 多項排序 rs = User.objects.order_by('age', '-id') # 獲取當前查詢到的數據的總數,隻需要在查找後面加上count方法即可 rs = User.objects.filter(age=28).count() # 將返回的QuerySet中的Model轉換成字典,轉換成字典之後,我們可以進行迭代用鍵取值 rs = User.objects.all().values() for i in rs: print(i['name']) print(rs)
4.3查詢條件
# 常用查詢條件 # 相當於WHERE語句後面的提交,傳給查詢方法的一些參數 # 語法規則 :字段名__條件, 註意是兩個下劃線 # 等於 rs = User.objects.filter(age=18) # 包含 模糊查詢 rs = User.objects.filter(name__contains='j') # 大於 rs = User.objects.filter(age__gt=18) # 大於等於 rs = User.objects.filter(age__gte=18) # 小於 rs = User.objects.filter(age__lt=18) # 小於等於 rs = User.objects.filter(age__lte=18) # 判斷是否為空 rs = User.objects.filter(city__isnull=True) # 以什麼開始 rs = User.objects.filter(name__startwith='z') # 以什麼結尾 rs = User.objects.filter(name__endwith='1') # 多個條件 成員所屬,是否在我們給的列表條件中 rs = User.objects.filter(name__in=['zj', 'zjj', 'zjjjj']) # 范圍 包含開頭和結尾 rs = User.objects.filter(age__range=(18, 28))
4.4聚合查詢
Count, Avg, Min, Max, Sum主要有這些方法
from django.db.models import Count, Avg, Min, Max, Sum, F, Q # 可以使用聚合查詢進行聚合查詢, Count,Avg, Max, Min, Sum.這是需要導入的 # aggregate()是QuerySet的一個終止語句,返回的是一個包含鍵值對的字典 # 統計條數 rs = User.objects.all().aggregate(Count('age')) # 求年齡平均值 rs = User.objects.all().aggregate(Avg('age')) # 求年齡最大值 rs = User.objects.all().aggregate(Max('age')) # 求年齡最小值 rs = User.objects.all().aggregate(Min('age')) # 年齡求和 rs = User.objects.all().aggregate(Sum('age')) # 可以修改key的值 以上的返回值都是一個鍵值對,我們可以更改key的值 rs = User.objects.all().aggregate(ageSum=Sum('age'))
4.5分組查詢
# 分組查詢 # 調用的QuerySet中每個對象都生成一個獨立的統計值 # 拿出需要分組的字段 values方法是獲得括號裡,在數據庫中所有該屬性的值,並返回鍵值對類型的字典 rs = User.objects.values('age') # 對age這個字段進行分組 ,這裡使用的計數函數,即返回的字典裡顯示該age的個數的鍵值對 rs = rs.annotate(count=Count('age')) # 或者使用這個方法 rs = User.objects.values('age').annotate(count=Count('age'))
F和Q查詢
from django.db.models import F, Q # F查詢 也需要導入 # 給User表中的所有人加一歲(+1), 減一歲就-1 rs = User.objects.all().update(age=F('age') + 1) # Q查詢 # 如果需要執行更加復雜的查詢,可以使用Q對象 # & (and) | (or) ~ (not) # 查詢名字尾zj或者年齡為18的用戶 rs = User.objects.filter(Q(name='zj') | Q(age=18)) # 查詢名字為zjjj,並且年齡不等於28 rs = User.objects.filter(Q(name='zjjj') & ~Q(age=28)) print(rs) return HttpResponse('查找成功')
Q查詢一般用於邏輯查詢
到此這篇關於Django與數據庫交互的實現的文章就介紹到這瞭,更多相關Django 數據庫交互內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!