Django Models 一對多,多對多,多對一關係解析
阿新 • • 發佈:2019-02-15
1、資料型別
1)CharField 和TextField
2)EmailField, URLField 和IPAddressField
3)BooleanField 和NullBooleanField
4)FileField
2、類的關聯關係 classAuthor(models.Model): name =models.CharField(max_length=100) 1)一對多關係 classBook(models.Model): title =models.CharField(max_length=100) author =models.ForeignKey("Author") book= Book.objects.get(title="Django") author = Book.author #獲取該圖書的作者 books= author.book_set.all() # 獲取該作者的所有圖書
2)多對多關係
classBook(models.Model):
title =models.CharField(max_length=100)
authors =models.ManyToManyField(Author)
book= Book.objects.get(title="Django")
authors = Book.author_set.all() # 獲取該書的作者名單
books= author[2].book_set.all() # 獲取第三作者所著的所有圖書
3)多對多關係--通過第三個類
classBook(models.Model):
title =models.CharField(max_length=100)
authors =models.ManyToManyField(Author, through="Authoring")
classAuthoring(models.Model):
collaboration_type =models.CharField(max_length=100)
book =models.ForeignKey(Book)
author =models.ForeignKey(Author)
chun_essay_compilations = Book.objects.filter(
author__name__endswith='Chun',
authoring__collaboration_type='essay'
)
4)帶約束的多對多關係
classBook(models.Model):
title =models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
def __unicode__(self):
returnself.title
class Meta:
abstract =True
ordering =['title']
classSmithBook(Book):
authors = models.ManyToManyField(Author,limit_choices_to={
'name__endswith': 'Smith'
})
3、資料查詢
1)all
people =Person.objects.all().order_by('first')
2)filter
books_about_trees =Book.objects.filter(title__contains="Tree")
# SELECT *FROM myapp_book WHERE title LIKE "%Tree%"
john_does =Person.objects.filter(last="Doe", first="John")
# SELECT *FROM myapp_person WHERE last = "Doe" AND first = "John"
today =datetime.now()
overdue_books =book_queryset.filter(due_date__lt = today)
3)exclude
4)get
5)values
Person.objects.values('first')
# SELECT first FROMmyapp_person;
Person.objects.values_list('first')
Django 的 ORM 有多種關係:一對一,多對一,多對多。 各自定義的方式為 : 一對一: OneToOneField 多對一: ForeignKey 多對多: ManyToManyField 上邊的描述太過資料而缺乏人性化,我們來更人性化一些: 多個屬於一個,即 belong to : ForeignKey,多個屬於一個 一個有一個,即 has one: OneToOneField 一個有很多個,即 has many: lots of A belong to B 與 B has many A,在建立 ForeignKey 時,另一個表會自動建立對應的關係 一個既有很多個,又屬於很多個,即 has many and belong to : ManyToManyField,同樣只能在一個model類中說明,關聯表會自動建立。 訪問方式: 以下程式碼摘自 StackOverflow 用來說明訪問方式
2、類的關聯關係 classAuthor(models.Model): name =models.CharField(max_length=100) 1)一對多關係 classBook(models.Model): title =models.CharField(max_length=100) author =models.ForeignKey("Author") book= Book.objects.get(title="Django") author = Book.author #獲取該圖書的作者 books= author.book_set.all()
Django 的 ORM 有多種關係:一對一,多對一,多對多。 各自定義的方式為 : 一對一: OneToOneField 多對一: ForeignKey 多對多: ManyToManyField 上邊的描述太過資料而缺乏人性化,我們來更人性化一些: 多個屬於一個,即 belong to : ForeignKey,多個屬於一個 一個有一個,即 has one: OneToOneField 一個有很多個,即 has many: lots of A belong to B 與 B has many A,在建立 ForeignKey 時,另一個表會自動建立對應的關係 一個既有很多個,又屬於很多個,即 has many and belong to : ManyToManyField,同樣只能在一個model類中說明,關聯表會自動建立。 訪問方式: 以下程式碼摘自 StackOverflow 用來說明訪問方式
Model Code
from django.db import models
classEngine(models.Model):
name = models.CharField(max_length=25)def __unicode__(self):returnself.name
classCar(models.Model):
name = models.CharField(max_length=25)
engine = models.OneToOneField(Engine)def __unicode__(self):returnself.name
classEngine2(models.Model):
name = models.CharField(max_length=25)def __unicode__(self):returnself.name
classCar2(models.Model):
name = models.CharField(max_length=25)
engine = models.ForeignKey(Engine2, unique=True)def __unicode__(self):returnself.name
OneToOneField
Example
>>>from testapp.models importCar,Engine>>> c =Car.objects.get(name='Audi')>>> e =Engine.objects.get(name='Diesel')>>> e.car #engine 的model 定義中並沒有car,這個是自動生成的,用關聯表的類名小寫直接訪問
<Car:Audi> # 注意返回內容的不同
ForeignKey
with unique=True
Example
>>>from testapp.models importCar2,Engine2>>> c2 =Car2.objects.get(name='Mazda')>>> e2 =Engine2.objects.get(name='Wankel')>>> e2.car2_set.all() # 在未定義的model中用關聯表類名小寫加"_set"來訪問,多對多也一樣[<Car2:Mazda>] #注意返回內容的不同,這裡是一個QuerySet
以下內容摘自DjangoBook,僅供個人查詢使用:
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __unicode__(self):
return self.name
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
def __unicode__(self):
return self.title
如我們在第5章的講解,獲取資料庫物件的特定欄位的值只需直接使用屬性。 例如,要確定ID為50的書本的標題,我們這樣做:
>>> from mysite.books.models import Book
>>> b = Book.objects.get(id=50)
>>> b.title
u'The Django Book'
但是,在之前有一件我們沒提及到的是表現為ForeignKey 或 ManyToManyField的關聯物件欄位,它們的作用稍有不同。
訪問外來鍵(Foreign Key)值
當你獲取一個ForeignKey 欄位時,你會得到相關的資料模型物件。 例如:
>>> b = Book.objects.get(id=50)
>>> b.publisher
<Publisher: Apress Publishing>
>>> b.publisher.website
u'http://www.apress.com/'
對於用`` ForeignKey`` 來定義的關係來說,在關係的另一端也能反向的追溯回來,只不過由於不對稱性的關係而稍有不同。 通過一個`` publisher`` 物件,直接獲取 books ,用 publisher.book_set.all() ,如下:
>>> p = Publisher.objects.get(name='Apress Publishing')
>>> p.book_set.all()
[<Book: The Django Book>, <Book: Dive Into Python>, ...]
實際上,book_set 只是一個 QuerySet(參考第5章的介紹),所以它可以像QuerySet一樣,能實現資料過濾和分切,例如:
>>> p = Publisher.objects.get(name='Apress Publishing')
>>> p.book_set.filter(name__icontains='django')
[<Book: The Django Book>, <Book: Pro Django>]
屬性名稱book_set是由模型名稱的小寫(如book)加_set組成的。
訪問多對多值(Many-to-Many Values)
多對多和外來鍵工作方式相同,只不過我們處理的是QuerySet而不是模型例項。 例如,這裡是如何檢視書籍的作者:
>>> b = Book.objects.get(id=50)
>>> b.authors.all()
[<Author: Adrian Holovaty>, <Author: Jacob Kaplan-Moss>]
>>> b.authors.filter(first_name='Adrian')
[<Author: Adrian Holovaty>]
>>> b.authors.filter(first_name='Adam')
[]
反向查詢也可以。 要檢視一個作者的所有書籍,使用author.book_set ,就如這樣:
>>> a = Author.objects.get(first_name='Adrian', last_name='Holovaty')
>>> a.book_set.all()
[<Book: The Django Book>, <Book: Adrian's Other Book>]
這裡,就像使用 ForeignKey欄位一樣,屬性名book_set是在資料模型(model)名後追加_set。