成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

orm詳解

博客園    首頁    博問    閃存    新隨筆    訂閱 orm 詳解    管理

ORM:(在django中,根據(jù)代碼中的類自動(dòng)生成數(shù)據(jù)庫的表也叫--code first)

ORM:Object Relational Mapping(關(guān)系對(duì)象映射)

我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、循化ssl等。為上千余家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的循化網(wǎng)站制作公司

我們寫的類表示數(shù)據(jù)庫中的表

我們根據(jù)這個(gè)類創(chuàng)建的對(duì)象是數(shù)據(jù)庫表里的一行數(shù)據(jù)

obj.id  obj.name.....就是數(shù)據(jù)庫一行數(shù)據(jù)中的一部分?jǐn)?shù)據(jù)

ORM--First:

我們?cè)趯W(xué)習(xí)django中的orm的時(shí)候,我們可以把一對(duì)多,多對(duì)多,分為正向和反向查找兩種方式。

1
2
3
4
5
6
7
class UserType(models.Model):
    caption = models.CharField(max_length=32)
 
class UserInfo(models.Model):
    username = models.CharField(max_length=32)
    age = models.IntegerField()
    user_type = models.ForeignKey('UserType')#外鍵

正向查找:ForeignKey在 UserInfo表中,如果從UserInfo表開始向其他的表進(jìn)行查詢,這個(gè)就是正向操作,反之如果從UserType表去查詢其他的表這個(gè)就是反向操作。

馬上就要開始我們的orm查詢之旅!?。?

建表+配置url+views中寫相應(yīng)的函數(shù)

models.py(在django中僅且只能在這里寫數(shù)據(jù)庫的相關(guān)類)

1
2
3
4
5
6
7
class UserType(models.Model):
    caption = models.CharField(max_length=32)
 
class UserInfo(models.Model):
    username = models.CharField(max_length=32)
    age = models.IntegerField()
    user_type = models.ForeignKey('UserType')

這里我們使用sqlite3數(shù)據(jù)庫,在settings中使用默認(rèn)設(shè)置就可以了

url.py中的配置

1
2
3
4
5
6
7
8
9
from django.conf.urls import url
from django.contrib import admin
from app01 import views
 
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^user_type',views.user_type),
    url(r'^user_info',views.user_info),
]

views.py先不進(jìn)行任何操作,我們先保證正常訪問已經(jīng)設(shè)置的url

1
2
3
4
5
6
7
from django.shortcuts import render,HttpResponse
 
def user_type(req):
    return HttpResponse("ok")
 
def user_info(req):
    return HttpResponse("ok")

先在表中插入幾個(gè)數(shù)據(jù)用于測(cè)試:

usertype表

orm 詳解

userinfo表數(shù)據(jù)插入:

所以我們?cè)趧?chuàng)建UserType數(shù)據(jù)的時(shí)候有兩種方法:第一種方法是直接根據(jù)這個(gè)字段進(jìn)行添加數(shù)據(jù)!給user_type 加 '_id'

1
2
3
4
def user_info(request):
    dic = {'username':'mosson','age':18,'user_type_id':1}
    models.UserInfo.objects.create(**dic)
    return HttpResponse('OK')

或者通過對(duì)象添加

1
2
3
4
5
6
7
#先獲取組的對(duì)象
usertype = models.UserType.objects.fiter(id=2)
#添加的時(shí)候直接添加對(duì)象就可以
models.UserInfo.objects.create(username='seven',age=18,user_type=usertype)
 
#寫成一行也行
models.UserInfo.objects.create(username='lile',age=18,user_type=models.UserType.objects.filter(id=1))

django的get方法是從數(shù)據(jù)庫的取得一個(gè)匹配的結(jié)果,返回一個(gè)對(duì)象,如果記錄不存在的話,它會(huì)報(bào)錯(cuò)。
django的filter方法是從數(shù)據(jù)庫的取得匹配的結(jié)果,返回一個(gè)對(duì)象列表,如果記錄不存在的話,它會(huì)返回[]。

orm 詳解

ORM的一對(duì)多:

我們?cè)谠O(shè)計(jì)表結(jié)構(gòu)的時(shí)候什么時(shí)候使用一對(duì)多呢?

比如我們?cè)诮⒂脩舻臅r(shí)候有個(gè)菜單讓我們選擇用戶類型的時(shí)候,使用一對(duì)多??!

1、一對(duì)多的正向查找:

正向查:ForeignKey在UserInfo表里,如果根據(jù)UserInfo這張表去查詢這兩張關(guān)聯(lián)的表的合起來的內(nèi)容就是正向查

反向查:ForeignKey不在UserType里,如果根據(jù)UserType這張表去查詢這兩張關(guān)聯(lián)的表的合起來的內(nèi)容就是反向查

正向查-demo1--查詢所有用戶為COO 的用戶

在django中外鍵就相當(dāng)于簡單的使用__連表,在外鍵那個(gè)對(duì)象中封裝了user_type表中的所有字段

我們要查詢所有用戶為CEO的用戶,我們是不是的根據(jù)UserType這張表去查,如果是跨表查詢使用“雙下劃線” + 屬性

1
2
3
4
5
6
7
from app01 import models
def index(req):
    ret = models.UserInfo.objects.filter(user_type__caption='COO')
    print(ret)
    for item in ret:
        print(item,item.username,item.age,item.user_type.caption)
    return HttpResponse("OK")

查詢結(jié)果:

orm 詳解

反向查詢:--

我們可以根據(jù)下面的命令,取出一個(gè)用戶組,那么對(duì)于這個(gè)用戶組他有多少個(gè)用戶呢?

1
models.UserType.objects.get(id=1)
1
2
3
4
5
6
7
8
9
10
11
obj=models.UserType.objects.get(id=1)
    obj.caption====得到在UserType表中id為1對(duì)應(yīng)的caption
    obj.id======得到在UserType表中id為1
    obj.userinfo_set  #理解為一種能力,可以獲取所有當(dāng)前這個(gè)用戶類型的用戶/或者這個(gè)用戶類型的多個(gè)用戶
    obj.userinfo_set.all() #獲取所有用戶類型為COO的用戶
    obj.userinfo_set.filter(username='tim') #獲取用戶類型為COO的并且用戶為tim的用戶
 
    '''
    這.userinfo_set.相當(dāng)于什么?它相當(dāng)于  models.UserInfo.objects.filter(user_type=obj)
 
    '''

反向查詢實(shí)例:查詢COO用戶下的所有的用戶名

1
2
3
ret = models.UserType.objects.filter(caption='COO').values('userinfo__username')
   for item in ret:
       print(item,type(item))

方法二、

1
2
3
4
ret = models.UserType.objects.filter(caption='COO').first()
 
    for item in  ret.userinfo_set.all():
        print(item.username)

總結(jié):

  正向查找:

    filter(跨表的時(shí)候,應(yīng)該是對(duì)象__跨表的字段)

    獲取這個(gè)值的時(shí)候,拿到了一行數(shù)據(jù)的時(shí)候 line.對(duì)象.跨表的字段

  反向查找:

    filter(關(guān)聯(lián)這個(gè)表的表明) 自動(dòng)創(chuàng)建和表明相同的對(duì)象,通過這個(gè)對(duì)象__跨表的字段

    line.自動(dòng)創(chuàng)建和表明相同的對(duì)象_set.方法

orm 詳解

ORM多對(duì)多  系統(tǒng)生成第三張表:

多對(duì)多和一對(duì)多沒有任何關(guān)系

models.py

1
2
3
4
5
6
7
8
class Host(models.Model):
    hostname = models.CharField(max_length=32)
    port = models.IntegerField()
 
class HostAdmin(models.Model):
    username = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    host = models.ManyToManyField('Host')

當(dāng)我們?cè)趆ost表里和hostadmin表里添加數(shù)據(jù)時(shí)和第三章關(guān)系表沒有任何關(guān)系,當(dāng)我們這樣去建立表時(shí),第三張表里面的列就已經(jīng)固定了,分別是這兩個(gè)表的id

給主機(jī)表添加數(shù)據(jù):

1
2
3
4
5
6
7
8
9
10
11
def index(req):
    #主機(jī)數(shù)據(jù)
    models.Host.objects.create(hostname='host1.test.com', port=80)
    models.Host.objects.create(hostname='host2.test.com', port=80)
    models.Host.objects.create(hostname='host3.test.com', port=80)
    models.Host.objects.create(hostname='host4.test.com', port=80)
    #用戶數(shù)據(jù)
    models.HostAdmin.objects.create(username='alex', email='alex@qq.com')
    models.HostAdmin.objects.create(username='mosson', email='mosson@qq.com')
    models.HostAdmin.objects.create(username='aliven', email='aliven@qq.com')
    models.HostAdmin.objects.create(username='wusir', email='wusir@qq.com')

數(shù)據(jù)中的效果:

orm 詳解

orm 詳解

空的關(guān)系表

orm 詳解

多對(duì)多正向、反向添加數(shù)據(jù)

orm 詳解

正向添加數(shù)據(jù):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def index(request):
 
    #正向添加數(shù)據(jù)
 
    #找到用戶dali這個(gè)
    admin_obj = models.HostAdmin.objects.get(username='dali')
    #找到主機(jī)
    host_list = models.Host.objects.filter(id__lt=3)
    #通過找到的dali的對(duì)象.add去添加數(shù)據(jù)
    admin_obj.host.add(*host_list)
    '''
    admin_obj 通過大力這個(gè)對(duì)象.add 去操作的主機(jī),
    大力的ID為 2 主機(jī)ID為:(1,2)
    那就會(huì)生成這樣的表:
    #2 1
    #2 2
    '''
    return HttpResponse('OK')

反向添加數(shù)據(jù):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def index(request):
 
    #反向添加數(shù)據(jù)
    #獲取主機(jī)
    host_obj = models.Host.objects.get(id=3)
    #獲取用戶列表
    admin_list = models.HostAdmin.objects.filter(id__gt=1)
    #和一對(duì)多一樣的道理
    host_obj.hostadmin_set.add(*admin_list)
    #host_obj = 3   管理員ID = 2 3 4
    #3 2
    #3 3
    #3 4   
    return HttpResponse('OK')

ORM 多對(duì)多 自定義 第三張表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class HostInfo(models.Model):
    hostname = models.CharField(max_length=32)
    port = models.IntegerField()
 
class UserMap(models.Model):
    username = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
 
    #through告訴Django用那張表做關(guān)聯(lián)
    host = models.ManyToManyField(HostInfo , through='HostRelation')
 
class HostRelation(models.Model):
    host = models.ForeignKey('HostInfo')
    user = models.ForeignKey('UserMap')
 
    '''
    并且這里我們可以添加多個(gè)關(guān)系,比如在加一個(gè)字段
    usertype = models.ForeignKey('UserType')
    或者增加一個(gè)普通字段
    status = models.CharField(max_length=32)
    '''

現(xiàn)在咱們自己創(chuàng)建了第三張表了?,F(xiàn)在我們已經(jīng)會(huì)了兩種方式創(chuàng)建第三張表了,當(dāng)我們使用自定義創(chuàng)建的第三張表的時(shí)候,在去添加數(shù)據(jù)的時(shí)候!

就不能使用第一種方式對(duì)象添加了!

現(xiàn)在我們有第三張表了這個(gè)對(duì)象了,我們就不需要管另外兩張表了,直接添加就行了! 0 0 !

添加主機(jī)和用戶--

1
2
3
4
5
6
7
8
9
10
11
def index(req):
 
    models.HostInfo.objects.create(hostname='alex.test.com', port=80)
    models.HostInfo.objects.create(hostname='seven.test.com', port=80)
    models.HostInfo.objects.create(hostname='mosson.test.com', port=80)
 
    models.UserMap.objects.create(username='alex', email='alex@qq.com')
    models.UserMap.objects.create(username='seven', email='seven@qq.com')
    models.UserMap.objects.create(username='mosson', email='mosson@qq.com')
 
    return HttpResponse('ok')

將數(shù)據(jù)插入到第三張表中---辦法1:

插入單條數(shù)據(jù)

1
2
3
4
5
6
def index(request):
    models.HostRelation.objects.create(
        user = models.UserMap.objects.get(id=1),
        host = models.HostInfo.objects.get(id=1)
    )
    return HttpResponse('OK')

多對(duì)多兩種方式對(duì)比和查詢

orm 詳解

查詢--方法一:

第一種方式都是基于表中的對(duì)象去找到第三張表! 通過間接的方式找到這張表的句柄!

1
2
3
4
5
6
#正向查
admin_obj = models.HostAdmin.objects.get(id=1)
admin_obj.host.all()
#反相差
host_obj = models.Host.objects.get(id=1)
host_obj.hostadmin_set.all()

查詢--方法二:

用第二種方法就沒有正向和反向這么一說了,直接查即可!

1
2
3
4
relation_list = models.HostRelation.objects.all()
for item in relation_list:  #每一個(gè)item就是一個(gè)關(guān)系
    print (item.user.username)
    print( item.host.hostname)
1
2
3
4
relation_list = models.HostRelation.objects.filter(user__username='mosson')
    for item in relation_list:  #每一個(gè)item就是一個(gè)關(guān)系
        print( item.user.username)
        print (item.host.hostname)

通過第二種方式可以把所有的關(guān)系都找到,第一種方式可以把所有的關(guān)系表都找到嗎?

第一種方式只能找到某一個(gè)人管理的機(jī)器,不能把有的對(duì)應(yīng)關(guān)系找到!

select_related的作用:

1
2
3
4
5
6
7
class UserType(models.Model):
    caption = models.CharField(max_length=32)
 
class UserInfo(models.Model):
    user_type = models.ForeignKey('UserType') #這個(gè)user_type是一個(gè)對(duì)象,對(duì)象里面封裝了ID和caption
    username = models.CharField(max_length=32)
    age = models.IntegerField()

select_related的作用,他就是用來優(yōu)化查詢的,沒有他也可以,用它主要是用來優(yōu)化ForeignKey

1
2
3
4
5
6
7
def index(request):
    ret = models.UserInfo.objects.all()
    #咱們看下他執(zhí)行的什么SQL語句
    print( ret.query)
'''
SELECT "app01_userinfo"."id", "app01_userinfo"."user_type_id", "app01_userinfo"."username", "app01_userinfo"."age" FROM "app01_userinfo"
'''

加上select_related是什么樣子的

名稱欄目:orm詳解
文章轉(zhuǎn)載:http://jinyejixie.com/article10/ijchgo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)、標(biāo)簽優(yōu)化、定制網(wǎng)站、虛擬主機(jī)、動(dòng)態(tài)網(wǎng)站、小程序開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

猜你還喜歡下面的內(nèi)容

成都定制網(wǎng)站建設(shè)
禄劝| 尼木县| 敖汉旗| 刚察县| 沭阳县| 萍乡市| 襄城县| 商丘市| 上虞市| 绥化市| 伊春市| 交城县| 大埔县| 灵石县| 阿勒泰市| 灵台县| 南充市| 宣城市| 隆德县| 鄂州市| 廊坊市| 莆田市| 乡城县| 绥江县| 额尔古纳市| 临澧县| 台湾省| 佛教| 新沂市| 开原市| 安仁县| 内乡县| 百色市| 丹巴县| 南康市| 南安市| 铁岭县| 皋兰县| 巩义市| 鸡东县| 年辖:市辖区|