Django ORM查詢操作方式
Django提供了一套非常方便的類(lèi)似SqlAlchemy ORM的通過(guò)對(duì)象調(diào)用的方式操作數(shù)據(jù)庫(kù)表的ORM框架。
Django ORM操作主要分為以下幾類(lèi):
- 增:向表內(nèi)插入一條數(shù)據(jù)
- 刪:刪除表內(nèi)數(shù)據(jù)(物理刪除)
- 改:update操作更新某條數(shù)據(jù)
- 查:基本的表查詢(包括多表、跨表、子查詢、聯(lián)表查詢)
其中比較復(fù)雜的是表查詢。下面分類(lèi)講解這幾種操作方式。
1 增 – 向表內(nèi)插入一條數(shù)據(jù)
關(guān)于新增記錄的操作這里分為兩種方式:
第一種方式,通過(guò)模型對(duì)象的save()方法:
userObj=User()
userObj.username= request.data.get('username')
# userObj.password= make_password(request.POST.get('password'),None,'pbkdf2_sha256') # 創(chuàng)建django密碼,第三個(gè)參數(shù)為加密算法
userObj.set_password(request.data.get('password')) # 創(chuàng)建django密碼,第三個(gè)參數(shù)為加密算法
userObj.name= request.data.get('name')
userObj.phone= request.data.get('phone')
userObj.email= request.data.get('email')
userObj.create_name= request.data.get('create_name')
userObj.update_name= request.data.get('update_name')
userObj.is_superuser= 0
print(userObj.username)
print('username %s' % (userObj.username))
print('password %s' % (userObj.password))
userObj.save()
這種方式先創(chuàng)建一個(gè)模型對(duì)象,賦值,最后調(diào)用模型的 .save()方法的方式向數(shù)據(jù)庫(kù)插入一條數(shù)據(jù)。
第二種方式,通過(guò)objects.create的方式直接新增,類(lèi)似一種縮略的方式,比較簡(jiǎn)單
res = models.User.objects.create(username='admin',make_password='123456',register_time=datetime.datetime.now()) print(res)
2 刪 – 刪除表內(nèi)數(shù)據(jù)(物理刪除)
django刪除表數(shù)據(jù)是通過(guò).delete()方法,舉例:
如果我們只刪除 user表 主鍵為1的記錄:
ret = models.User.objects.get(pk=1).delete()
上述是只刪一條記錄,刪除多條記錄類(lèi)似:ret = models.User.objects.filter(pk__gt=1).delete()
這樣我們可以批量刪除user表中主鍵值大于1的其他所有記錄。
需要提醒的是,這種方式屬于物理刪除,刪除后不可恢復(fù),如需邏輯刪除,參考下面 update的方式。
3 改 – update操作更新某條數(shù)據(jù)
django ORM 的改操作,這里分為三種方式。我們先按單記錄的更新講解,批量更新類(lèi)似:
第一種,指定更新字段更新:
ret = models.User.objects.get(pk=1).update(username='admin',password='123456')
第二種,通過(guò) Json 更新:
object = {'username':'admin','password':'123456'}
ret = models.User.objects.get(pk=1).update(**object)第三種,類(lèi)似增操作,直接通過(guò).save()方法更新整條記錄
userObj=User()
userObj.id= request.data.get('id')
userObj.username= request.data.get('username')
# userObj.password= make_password(request.POST.get('password'),None,'pbkdf2_sha256') # 創(chuàng)建django密碼,第三個(gè)參數(shù)為加密算法
userObj.set_password(request.data.get('password')) # 創(chuàng)建django密碼,第三個(gè)參數(shù)為加密算法
userObj.name= request.data.get('name')
userObj.phone= request.data.get('phone')
userObj.email= request.data.get('email')
userObj.create_name= request.data.get('create_name')
userObj.update_name= request.data.get('update_name')
userObj.is_superuser= 0
print(userObj.username)
print('username %s' % (userObj.username))
print('password %s' % (userObj.password))
userObj.save()這種方式不太建議用,需要注意數(shù)據(jù)的完整性。
4 查 – 基本的表查詢(包括多表、跨表、子查詢、聯(lián)表查詢)
4.1 基本查詢
需要了解如下方法的使用:
all()查詢所有數(shù)據(jù)filter()帶有過(guò)濾條件的查詢whereget()獲取單條,查詢不到會(huì)報(bào)錯(cuò)first()取queryset里第一條記錄last()取queryset里最后一條記錄values()指定要獲取的字段
models.User.objects.filter(pk=1).values('username','phone')
# 返回 <QuerySet [{'username': 'admin', 'phone': '176****'}]>values_list() 列表套元祖
models.User.objects.filter(pk=1).values_list('username','phone')
# 返回 <QuerySet [('admin','176***')]>distinct() 去重
ret = models.User.objects.filter(pk=1).distinct()
需要注意,這里去重是針對(duì)整條數(shù)據(jù)的去重,主鍵不一樣也不會(huì)去重
order_by() 排序
ret = models.User.objects.order_by('username')# 默認(rèn)升序
ret = models.User.objects.order_by('-username')# 降序reverse() 反轉(zhuǎn),前提已排序
ret = models.User.objects.order_by('username').reverse()# 默認(rèn)升序
ret = models.User.objects.order_by('-username').reverse()# 降序count() 當(dāng)前查詢條件的記錄數(shù)
ret = models.User.objects.filter(pk=1).count()
exclude() 排除 ,相當(dāng)于查詢條件不等于
ret = models.User.objects.exclude(pk=1)
exists() 記錄是否存在,不太實(shí)用,不過(guò)多講
4.2 雙下劃線查詢條件
django不支持 類(lèi)似:>=,<=等查詢判斷方式,但提供了一套很好用的方法:
__gt<=> 大于:ret = models.User.objects.filter(id__gt=1)#查詢id>1的記錄__lt<=> 小于:ret = models.User.objects.filter(id__lt=1)#查詢id<1的記錄__gte<=> 大于等于:ret = models.User.objects.filter(id__gte=1)#查詢id>=1的記錄__lte<=> 小于等于:ret = models.User.objects.filter(id__lte=1)#查詢id<=1的記錄__in<=> 條件是否歸屬所給的選擇:ret = models.User.objects.filter(id__in=[1,2])#查詢id=1或id=2的記錄__range<=> 范圍:ret = models.User.objects.filter(id__range=[1,3])#查詢1<=id<=3的記錄__contains<=> 模糊查詢 ,區(qū)分大小寫(xiě):ret = models.User.objects.filter(username__contains='a')#查詢 username like '%a%'的記錄__icontains<=> 模糊查詢 ,不區(qū)分大小寫(xiě):ret = models.User.objects.filter(username__icontains='a')#查詢 username like '%a%'的記錄__startswith<=> 模糊查詢 ,指定內(nèi)容開(kāi)始:ret = models.User.objects.filter(username__icontains='a')#查詢 username like 'a%'的記錄__endswith<=> 模糊查詢 ,指定內(nèi)容結(jié)束:ret = models.User.objects.filter(username__icontains='a')#查詢 username like '%a'的記錄
注意:__contains、__icontains、__startswith、__endswith這些模糊查詢性能很低,生產(chǎn)環(huán)境不建議使用。
4.3 邏輯查詢:or、and、not
涉及概念:Django的Q對(duì)象
4.3.1 Q對(duì)象
Q對(duì)象實(shí)例化后能夠增加各個(gè)條件之間的關(guān)系,而且這種寫(xiě)法用在你不知道用戶到底傳入了多少個(gè)參數(shù)的時(shí)候很方便。
比如默認(rèn)情況下filter()里面每個(gè)字段的連接都是&,我們使用Q對(duì)象通常都是讓它變成|,來(lái)進(jìn)行查詢 。
from django.db.models import Q
query = Q()
q1 = Q()
q1.connector = "AND" # 連接的條件是AND 代表就是&
q1.children.append(("email", "280773872@qq.com")) # email代表的是數(shù)據(jù)庫(kù)的字段
q1.children.append(("password", "666"))
# 等同于:email="280773872@qq.com" & password="666"
q2 = Q()
q2.connector = "AND" # 同樣q2對(duì)象連接條件也是AND
q2.children.append(("username", "fe_cow")) # 同樣數(shù)據(jù)庫(kù)里username字段
q2.children.append(("password", "fe_cow666"))
# 等同于:username="fe_cow" & password="fe_cow666"
query.add(q1, "OR")
query.add(q2, "OR")
# query目前里面的符合條件結(jié)果就是: (email="280773872@qq.com" & password="666") | (username="fe_cow" & password="fe_cow666")
userinfo_obj = models.UserInfo.objects.filter(query).first()filter()過(guò)濾器的方法中關(guān)鍵字參數(shù)查詢,會(huì)合并為And(),需要進(jìn)行or查詢,使用Q()對(duì)象,Q對(duì)象django.db.models.Q用于封裝一組關(guān)鍵字參數(shù),這些關(guān)鍵字參數(shù)與比較運(yùn)算符中的相同。
Q對(duì)象可以使用&(and)、|(or)操作符組合起來(lái),當(dāng)操作符應(yīng)用在兩個(gè)Q對(duì)象時(shí),會(huì)產(chǎn)生一個(gè)新的Q對(duì)象。
list.filter(pk__lt=6).filter(bcomment__gt=10) list.filter(Q(pk__lt=6) | Q(bcomment__gt=10))
- 使用
~操作符在Q對(duì)象前表示取反:list.filter(~Q(pk__lt=6)) - 可以使用
&|~結(jié)合括號(hào)進(jìn)行分組,構(gòu)造出復(fù)雜的Q對(duì)象
4.3.2 or、and、not
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'salary.settings')
django.setup(set_prefix=False)
from employee.models import Employees # 這一行必須在`os.environ.setdefault`之后,先把配置、環(huán)境變量準(zhǔn)備好后才能import
from django.db.models import Q
# emps = Employees.objects.all() # 懶查詢,只有后面對(duì)查詢結(jié)構(gòu)有引用時(shí),才會(huì)驅(qū)動(dòng)真正的查詢
# print(emps) # 查詢集
mgr = Employees.objects
# AND查詢: 五種方式
x = mgr.filter(pk__gt=10005, pk__lt=10010)
print(x)
y = mgr.filter(pk__gt=10005).filter(pk__lt=10010)
print(y)
z = mgr.filter(pk__gt=10005) & mgr.filter(pk__lt=10010)
print(z)
# Django的Q對(duì)象
xx = mgr.filter(Q(pk__gt=10005) & Q(pk__lt=10010))
yy = mgr.filter(Q(pk__gt=10005), Q(pk__lt=10010))
# OR查詢: 三種方式
x = mgr.filter(pk__in=[10005, 10010])
print(x)
y = mgr.filter(pk=10005) | mgr.filter(pk=10010)
print(y)
z = mgr.filter(Q(pk=10005) | Q(pk=10010))
# NOT查詢:
x = mgr.exclude(pk=10005)
print(x)
y = mgr.filter(~(Q(pk__gt=10005) & Q(pk__lt=10010)))
print(y)4.3.3 集合查詢
# 聚合
from django.db.models import Max, Min, Count, Sum, Avg
x = mgr.filter(pk__gt=10008).count() # 將所有數(shù)據(jù)看做一行出結(jié)構(gòu)
print(x) # 單值
# aggregate聚合函數(shù):出統(tǒng)計(jì)函數(shù)的結(jié)果,返回字典,默認(rèn)key命名為`字段名_聚合函數(shù)名`
y = mgr.filter(pk__gt=10008).aggregate(Count("pk"), Max("pk"), Min("pk"), sm_pk=Sum('pk'), avg_pk=Avg('pk')) # 可以給聚合查詢結(jié)果起別名
print(y)
# 結(jié)果:{'sm_pk': 120174, 'avg_pk': 10014.5, 'pk__count': 12, 'pk__max': 10020, 'pk__min': 10009}
# annotate聚合函數(shù):這個(gè)聚合函數(shù)會(huì)分組,沒(méi)有指定分組使用pk分組,行行分組。返回結(jié)果集
z = mgr.filter(pk__gt=10013).annotate(Count("pk"), Max("pk"), Min("pk"), sm_pk=Sum('pk'), avg_pk=Avg('pk'))
print(z)
xx = mgr.filter(pk__gt=10013).values('gender').annotate(c=Count("pk")).values("c") # 第一個(gè)values控制分組,第二個(gè)values控制投影
print(xx)4.4 多表查詢
4.4.1 一對(duì)多查詢
- Django不支持聯(lián)合主鍵,只支持單一主鍵,這一點(diǎn)和sqlalchemy不一樣
- Django不支持在Model中聲明編碼格式,這一點(diǎn)和sqlalchemy不一樣,只能在setting.py的DATABASES注冊(cè)中添加選項(xiàng)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test',
'USER': 'root',
'PASSWORD': 'cli*963.',
'HOST': '127.0.0.1',
'PORT': '3306',
},
'OPTIONS': {
'charset': 'utf8mb4',
}
}一對(duì)多模型構(gòu)造:
員工表 – 工資表是一對(duì)多的關(guān)系。由于django不支持聯(lián)合主鍵,需改造工資表。增加自增的id列,并設(shè)為主鍵,刪除其他主鍵和外鍵。
from django.db import models
# Create your models here.
class Employees(models.Model):
"""
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` enum('M','F') NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
"""
class Meta: # 數(shù)據(jù)庫(kù)表名,固定的,Django就是這樣定義,一個(gè)Meta類(lèi)
db_table = "employees" # 表名
emp_no = models.IntegerField(primary_key=True, null=False)
birth_date = models.DateField(null=False)
first_name = models.CharField(max_length=14, null=False)
last_name = models.CharField(null=False, max_length=16)
gender = models.SmallIntegerField(null=False)
hire_date = models.DateField(null=False)
# 在多端添加了外鍵屬性后,主端的(Employees)類(lèi)屬性字典__dict__中會(huì)自動(dòng)增加一個(gè)默認(rèn)名稱(chēng)為Salaries_set的屬性。
# 如果外鍵聲明的參數(shù)中使用了related_name=***,則這個(gè)屬性的名稱(chēng)變?yōu)閞elated_name指定的值
# 序列化
filed = '__all__'
depth = 1
def __repr__(self):
return "<Employee: {} {} {}>".format(self.emp_no, self.first_name, self.last_name)
@property
def full_name(self):
return "full name:{}-{}".format(self.first_name, self.last_name)
__str__ = __repr__
class Salaries(models.Model):
"""
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`) USING BTREE,
KEY `emp_no` (`emp_no`),
CONSTRAINT `salaries_ibfk_1` FOREIGN KEY (`emp_no`) REFERENCES `employees` (`emp_no`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
"""
class Meta:
db_table = "salaries"
# 一對(duì)多的多端,被引用的主表中的字段名emp_no,在多端(從表)的類(lèi)屬性字典__dict__中保存的key值為emp_no_id,實(shí)際上對(duì)應(yīng)了主表emp_no在數(shù)據(jù)庫(kù)中的值。
# 多端查詢這個(gè)被引用的外鍵值時(shí),也是拿著emp_no_id去主表中查的,此時(shí)會(huì)報(bào)key emp_no_id不存在異常。這種情況只需在外鍵聲明的參數(shù)中使用db_column='emp_no'指定key值。
emp_no = models.ForeignKey('Employees', models.CASCADE, db_column='emp_no')
# emp_no = models.ForeignKey('Employees', models.CASCADE, db_column='emp_no', related_name="salaries") # 使用related_name
salary = models.IntegerField(null=False)
from_date = models.DateField(null=False)
to_date = models.DateField(null=False)
id = models.AutoField(primary_key=True) # 自增
def __repr__(self):
return "<Salaries: {} {}>".format(self.emp_no_id, self.salary)
__str__ = __repr__如上示例,在Salaries Model模型類(lèi)中,創(chuàng)建ForeignKey外鍵。創(chuàng)建外鍵后:
- 一對(duì)多的多端:多端這里就是
Salaries定義的表。在這里,多端(從表)引用的主表的主鍵對(duì)應(yīng)的字段名為emp_no。 - 多端
Salaries的類(lèi)屬性字典__dict__中會(huì)自動(dòng)增加一個(gè)屬性,命名規(guī)則為被引用的字段名_id,這里就是emp_no_id, - 對(duì)應(yīng)主表在數(shù)據(jù)庫(kù)中
emp_no字段的值。在多端查詢時(shí),由于拿著emp_no_id去主表中查,而主表中的key為emp_no, - 導(dǎo)致報(bào)
key emp_no_id不存在錯(cuò)誤時(shí),這種情況需在外鍵聲明中加上db_column="emp_no"就可以了, - 表示不要用Django自動(dòng)命名的
emp_no_id去查,而是用指定的key值去主表中查。 - 一對(duì)多的一端:多端加了外鍵屬性后,主表類(lèi)屬性字典
__dict__中會(huì)自動(dòng)增加salaries_set屬性,命名規(guī)則默認(rèn)為多端表名_set。
如果在外鍵聲明中增加related_name="Salaries"參數(shù),則這個(gè)自動(dòng)增加的屬性名則使用related_name指定的值
所以:
- 從一端向多端查,則使用
instance.salaries_set - 從多端向一端查,則使用
instance.emp_no_id - 在多端的
__repr__中,為了提高效率不觸發(fā)主表查詢,也應(yīng)該用self.emp_no_id,而不是self.emp_no
print(*Employee.__dict__.items(), sep='\n')
# 一端,Employees類(lèi)中多了一個(gè)類(lèi)屬性
#('salaries_set', <django.db,models.fields.related_descriptors.ReverseManyTooneDescriptor object at 0x000001303FB09838>)
print(*salary._dict_,itemsO), sep='\n')
# 多端,Salaries類(lèi)中也多了一個(gè)類(lèi)屬性
#('emp_no_id',<django.db.models.query_utils.DeferredAttribute object at 0x000001303F809828>)
#('emp_no' <django.db.mode1s.fields.related_ descriptors. ForwardManyTo0neDescriptor object at 0x000001303FB09860>)指向Employees類(lèi)的一個(gè)實(shí)例查詢示例:
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'salary.settings')
django.setup(set_prefix=False)
from employee.models import Employees, Salaries # 這一行必須在`os.environ.setdefault`之后,先把配置、環(huán)境變量準(zhǔn)備好后才能import
print(Employees.__dict__.items())
print('_______________')
print(Salaries.__dict__.items())
print('______________')
emps = Employees.objects
sals = Salaries.objects
# 查詢10004號(hào)員工的工資
# 從員工表查詢,這個(gè)好,沒(méi)有冗余查詢
emp = emps.get(pk=10004) # 一個(gè)Employees對(duì)象
print(emp.salaries_set.all()) # 返回一個(gè)查詢結(jié)果集
# 從工資表查詢,這個(gè)不好,多對(duì)一,產(chǎn)生了冗余查詢
sal = sals.filter(emp_no=10004).all()
print(sal)distinct去重:
# 查詢工資大于5500的員工
_emps = sals.filter(salary__gt=5500).values('emp_no').distinct()
print(_emps)
print(emps.filter(emp_no__in=_emps)) # in子查詢
# print(emps.filter(emp_no__in=[x.get("emp_no") for x in _emps])) # in列表raw的使用:
對(duì)于非常復(fù)雜的sql語(yǔ)句,使用django ORM不好寫(xiě)了,可以使用raw,直接執(zhí)行sql語(yǔ)句。 例如:
# 查詢工資大于50000的所有員工的姓名 sql = """ SELECT DISTINCT e.* from employees as e JOIN salaries as s ON e.emp_no = s.emp_no WHERE salary > 50000 """ emgr = Employees.objects # 管理器 res = emgr.raw(sql) print(list(res))
更多學(xué)習(xí)案例請(qǐng)參考資料:https://juejin.cn/post/6974298891353063431
4.4.2 多對(duì)多查詢
多對(duì)多查詢有兩種建模方式:
借助第三張表。
例如一個(gè)員工可以在多個(gè)部門(mén),一個(gè)部門(mén)有多個(gè)員工。這種多對(duì)多的關(guān)系,可以增加第三張表"部門(mén)-員工表"。這樣多對(duì)多模型轉(zhuǎn)換為"多-1-多"的模型:部門(mén)表 - 部門(mén)&員工表 - 員工表"。最后查詢轉(zhuǎn)為為一對(duì)多的查詢。
使用models.ManyToManyField,構(gòu)建多對(duì)多模型。
models.ManyToManyField會(huì)自動(dòng)創(chuàng)建第三張表。models.ManyToManyField可以建在兩個(gè)模型類(lèi)中的任意一個(gè)。
下面以第二種方式舉例。
多對(duì)多模型: 一篇文章可以被多個(gè)用戶關(guān)注,一個(gè)用戶也可以關(guān)注多篇文章,二者是多對(duì)多的關(guān)系
模型構(gòu)建:
定義兩張表:User表(用戶表),Artile表(文章表)。
import datetime
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.hashers import make_password #密碼加密
class Artile(models.Model):
"""
title: 標(biāo)題
sub_title: 子標(biāo)題
content: 內(nèi)容
"""
def __str__(self):
return self.title
title = models.CharField(max_length=250,default='',verbose_name='標(biāo)題')
sub_title = models.CharField(max_length=250,default='',verbose_name='子標(biāo)題')
content = models.CharField(max_length=2000,default='',blank=True,verbose_name='內(nèi)容')
# 通過(guò)models.DateTimeField與User表建立多對(duì)多的關(guān)系,ManyToManyField可以建在兩個(gè)模型中的任意一個(gè),自動(dòng)創(chuàng)建第三張表
users = models.ManyToManyField(to='User', )
create_time = models.DateTimeField(default=datetime.datetime.now(),verbose_name='創(chuàng)建時(shí)間')
create_name = models.CharField(max_length=20,verbose_name='創(chuàng)建人')
update_time = models.DateTimeField(default=datetime.datetime.now(),blank=True,verbose_name='更新時(shí)間')
update_name = models.CharField(max_length=20,verbose_name='更新人',blank=True,)
is_delete = models.IntegerField(default=0,verbose_name='刪除狀態(tài)',blank=True,) # 邏輯刪除 0 正常 1:刪除
class Meta:
verbose_name = "文章"
verbose_name_plural = verbose_name
app_label = 'webApi'
class User(AbstractUser):
"""
name: 昵稱(chēng)
account: 用戶名
pwd: 密碼
phone:手機(jī)號(hào)
email:郵箱
avator:頭像
group_id:歸屬組
"""
def __str__(self):
return self.account
name = models.CharField(max_length=20,default='',verbose_name='昵稱(chēng)')
phone = models.CharField(max_length=20,default='',blank=True,verbose_name='手機(jī)號(hào)')
email = models.CharField(max_length=20,default='',blank=True,verbose_name='郵箱')
avator = models.CharField(max_length=200,default='',blank=True,verbose_name='頭像')
group_id = models.CharField(max_length=50,default='',blank=True,verbose_name='組')
create_time = models.DateTimeField(default=datetime.datetime.now(),verbose_name='創(chuàng)建時(shí)間')
create_name = models.CharField(max_length=20,verbose_name='創(chuàng)建人')
update_time = models.DateTimeField(default=datetime.datetime.now(),blank=True,verbose_name='更新時(shí)間')
update_name = models.CharField(max_length=20,verbose_name='更新人',blank=True,)
is_delete = models.IntegerField(default=0,verbose_name='刪除狀態(tài)',blank=True,) # 邏輯刪除 0 正常 1:刪除
# blank=True, 可選字段
class Meta:
verbose_name = "用戶"
verbose_name_plural = verbose_name
def __str__(self):
return self.username
# 明文密碼轉(zhuǎn)加密
def set_password(self, password):
print('set_password %s' % (password))
self.password = make_password(password,'jxy','pbkdf2_sha256')
# 驗(yàn)證密碼是否匹配
def check_password(self, password):
print('password: %s' % (password))
print('check_password: %s' % (make_password(password,'jxy','pbkdf2_sha256')))
print('self.password: %s' % (self.password))
return self.password == make_password(password,'jxy','pbkdf2_sha256')添加記錄:
向這張關(guān)系表中添加幾條關(guān)系。比如,我們將 Artile表主鍵為1的一條記錄,添加User表 主鍵為1,2兩條關(guān)系。
user1 = models.User.object.filter(pk=1).first() user2 = models.User.object.filter(pk=2).first() artile1 = models.Artile.object.filter(pk=1).first() artile1.users.add(user1,user2) # 方法二 userSet = models.User.object.filter(pk__in=[1,2]).all() artile1.users.add(*userSet)
這樣便在關(guān)系表中創(chuàng)建了 Artile表主鍵為1的記錄與User表主鍵為1,2的兩條關(guān)系。
另外清除關(guān)系綁定用法類(lèi)似,使用remove替代add:
artile1 = models.Artile.object.filter(pk=1).first() userSet = models.User.object.filter(pk__in=[1,2]).all() artile1.users.remove(*userSet) #解綁指定關(guān)系 artile1.users.clear() #清空所有關(guān)系
多對(duì)多查詢:
正向查詢,例如查詢Artile表第一條記錄有哪些用戶關(guān)注:
artile1 = models.Artile.object.filter(pk=1).first()
print(artile1.users.all().values('username')) # 打印關(guān)注Artile表第一條記錄的用戶名稱(chēng)逆向查詢,例如查詢User表第一條記錄關(guān)注過(guò)哪些Artile:
user1 = models.User.object.filter(pk=1).first()
print(user1.artile__set.all().values('title')) # 打印User表第一條記錄關(guān)注的文章名稱(chēng)總結(jié)
在開(kāi)發(fā)中,一般都會(huì)采用ORM框架,這樣就可以使用對(duì)象操作表了。
Django中,定義表映射的類(lèi),繼承自Model類(lèi)。Model類(lèi)使用了元編程,改變了元類(lèi)。使用Field實(shí)例作為類(lèi)屬性來(lái)描述字段。使用ForeignKey來(lái)定義外鍵約束。
到此這篇關(guān)于Django ORM查詢的文章就介紹到這了,更多相關(guān)Django ORM查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python實(shí)現(xiàn)簡(jiǎn)單淘寶秒殺功能
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)簡(jiǎn)單淘寶秒殺功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
pyinstaller 3.6版本通過(guò)pip安裝失敗的解決辦法(推薦)
這篇文章主要介紹了pyinstaller 3.6版本通過(guò)pip安裝失敗的解決辦法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01
利用Tensorboard繪制網(wǎng)絡(luò)識(shí)別準(zhǔn)確率和loss曲線實(shí)例
今天小編就為大家分享一篇利用Tensorboard繪制網(wǎng)絡(luò)識(shí)別準(zhǔn)確率和loss曲線實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02
深入挖掘Python自定義加密算法的設(shè)計(jì)與實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Python中自定義加密算法的設(shè)計(jì)與實(shí)現(xiàn)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-12-12
python 判斷txt每行內(nèi)容中是否包含子串并重新寫(xiě)入保存的實(shí)例
這篇文章主要介紹了python 判斷txt每行內(nèi)容中是否包含子串并重新寫(xiě)入保存的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03
python實(shí)現(xiàn)redis三種cas事務(wù)操作
本篇文章主要介紹了python實(shí)現(xiàn)redis三種cas事務(wù)操作,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
python實(shí)現(xiàn)隨機(jī)森林random forest的原理及方法
本篇文章主要介紹了python實(shí)現(xiàn)隨機(jī)森林random forest的原理及方法,詳細(xì)的介紹了隨機(jī)森林的原理和python實(shí)現(xiàn),非常具有參考價(jià)值,有興趣的可以了解一下2017-12-12
Python?pygame新手入門(mén)基礎(chǔ)教程
大家都知道pygame是跨平臺(tái)Python模塊,專(zhuān)為電子游戲設(shè)計(jì),包含圖像、聲音,這篇文章主要給大家介紹了關(guān)于Python?pygame新手入門(mén)基礎(chǔ)教程的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
tensorflow官方github預(yù)訓(xùn)練模型下載方式
這篇文章主要介紹了tensorflow官方github預(yù)訓(xùn)練模型下載方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02

