天天看點

Django(part34)--一對多映射

學習筆記,僅供參考

文章目錄

  • ​​資料表關聯關系映射​​
  • ​​一對多映射​​
  • ​​外鍵關聯ForeignKey​​
  • ​​構造函數​​
  • ​​舉個例子​​

資料表關聯關系映射

一對多映射

一對多是表示現實事物間存在的一對多的對應關系。比如,一個學生隻能屬于一個班級,一個班級可以有多個學生;一本圖書隻能屬于一個出版社,一個出版社允許出版多本書。

  • 文法

一個A類對象可以關聯多個B類對象

class A(model.Model):
    pass

class B(model.Model):
    屬性 = models.ForeignKey(A模型類, ...)      

外鍵關聯ForeignKey

構造函數
ForeignKey(to, on_delete, **options)      
  • 參數

on_delete

models.CASCADE 
#級聯删除,若設定此參數值,則當主對象被删除時,同時删除與其關聯的從屬對象。
models.PROTECT 
#如果主對象存在關聯對象時,我們删除主對象,就會抛出ProtectedError以阻止其被删除;
SET_NULL 
#當删除主對象時,從屬對象指向null
SET_DEFAULT 
#将ForeignKey設定為其預設值;必須設定ForeignKey的預設值。      

​**options​

​是常用的字段選項

null
unique
#等等      

舉個例子

  • 定義一對多類

models.py

from django.db import models

# Create your models here.

class Publisher(models.Model):
    name = models.CharField("出版社名", max_length = 50,null = True)
    booknumber = models.PositiveIntegerField("初版書籍總量", default = 0)
    tele = models.CharField("聯系電話", max_length = 11, null = False)
    class Meta:
        db_table = "china_publisher"
        verbose_name = "ChinaPublisher"
        verbose_name_plural  = "ChinaPublishers"
    def __str__(self):
        string = "出版社:%s" % (self.name)
        return string

class Book(models.Model):
    title = models.CharField("書名", max_length = 30)
    exfacPrice = models.DecimalField("出廠價", 
                                   max_digits = 6, decimal_places = 2,
                                   default = 0)
    
    price = models.DecimalField("售價", 
                              max_digits = 6, decimal_places = 2,
                              default = 0)
    pub = models.ForeignKey(Publisher, on_delete = models.CASCADE , null=True)
    
    def __str__(self):
        string = "書名:%s" % (self.title) 
        return string      
  • 建立一對多的對象

打開Django shell,敲入如下代碼:

from bookstore import models
pub1 = models.Publisher.objects.create(name='中國人民大學出版社', tele = "62511329", booknumber = 22000)
models.Book.objects.create(title='統計學', pub=pub1)
models.Book.objects.create(title='多元統計分析', pub=pub1)
models.Book.objects.create(title='回歸分析', pub=pub1)

pub2 = models.Publisher.objects.create(name='高等教育出版社', tele = "82080802", booknumber = 12000)
models.Book.objects.create(title='數學分析', pub=pub2)
models.Book.objects.create(title='高等代數', pub=pub2)      
  • 查詢

通過多查一:

#通過一本書找到對應的出版社
abook = models.Book.objects.get(title='統計學')
print(abook.title, '的出版社是:', abook.pub.name)      

輸出:

In [2]: abook = models.Book.objects.get(title='統計學')
   ...: print(abook.title, '的出版社是:', abook.pub.name)
   ...:
統計學 的出版社是: 中國人民大學出版社      

通過一查多:

#通過出版社查詢對應的書
pub1 = models.Publisher.objects.get(name='中國人民大學出版社')
books = pub1.book_set.all()  
#通過book_set擷取pub1對應的多個Book對象
#相當于
#books = models.Book.objects.filter(pub=pub1)  
print("清華大學出版社的書有:")
for book in books:
    print(book.title)      

輸出:

In [3]: #通過出版社查詢對應的書
   ...: pub1 = models.Publisher.objects.get(name='中國人民大學出版社')
   ...: books = pub1.book_set.all()
   ...: #通過book_set擷取pub1對應的多個Book對象
   ...: #相當于
   ...: #books = models.Book.objects.filter(pub=pub1)
   ...: print("清華大學出版社的書有:")
   ...: for book in books:
   ...:     print(book.title)
   ...:
清華大學出版社的書有:
統計學
多元統計分析
回歸分析      

我們看一下mywebdb資料庫中china_publisher資料表:

mysql> select * from china_publisher;
+----+--------------------+------------+----------+
| id | name               | booknumber | tele     |
+----+--------------------+------------+----------+
|  1 | 中國人民大學出版社 |      22000 | 62511329 |
|  2 | 高等教育出版社     |      12000 | 82080802 |
+----+--------------------+------------+----------+
2 rows in set (0.00 sec)      

再看一下mywebdb資料庫中bookstore_book資料表:

mysql> select * from bookstore_book;
+----+-------------------+------------+-------+--------+
| id | title             | exfacPrice | price | pub_id |
+----+-------------------+------------+-------+--------+
|  1 | Djangoweb開發實戰 |       0.00 |  0.00 |   NULL |
|  2 | python            |       0.00 |  0.00 |   NULL |
|  3 | R                 |       0.00 |  0.00 |   NULL |
|  5 | 算法              |       0.00 |  0.00 |   NULL |
|  6 | 集體智慧程式設計      |       0.00 |  0.00 |   NULL |
|  8 | 統計學            |       0.00 |  0.00 |      1 |
|  9 | 多元統計分析      |       0.00 |  0.00 |      1 |
| 10 | 回歸分析          |       0.00 |  0.00 |      1 |
| 11 | 數學分析          |       0.00 |  0.00 |      2 |
| 12 | 高等代數          |       0.00 |  0.00 |      2 |
+----+-------------------+------------+-------+--------+
10 rows in set (0.01 sec)      

bookstore_book資料表的pub_id字段關聯了china_publisher資料表中的id字段,是以​

​pub_id=1​

​​表示​

​中國人民大學出版社​

​​,​

​pub_id=2​

​​表示​

​高等教育出版社​

​。

最後,我們啟動服務,并向http://127.0.0.1:8000/admin/bookstore/book/發起請求:

Django(part34)--一對多映射

點選高等代數:

Django(part34)--一對多映射

可以看到,在​

​高等代數​

​​的記錄中,pub預設為​

​高等教育出版社​

​​,但是它有一個可選框,我們可以在​

​中國人民大學出版社​

​​和​

​高等教育出版社​

​之間選擇。

現在,我們将​

​高等代數​

​​的出版社改為​

​中國人民大學出版社​

​,并點選儲存。

mysql> select * from bookstore_book;
+----+-------------------+------------+-------+--------+
| id | title             | exfacPrice | price | pub_id |
+----+-------------------+------------+-------+--------+
|  1 | Djangoweb開發實戰 |       0.00 |  0.00 |   NULL |
|  2 | python            |       0.00 |  0.00 |   NULL |
|  3 | R                 |       0.00 |  0.00 |   NULL |
|  5 | 算法              |       0.00 |  0.00 |   NULL |
|  6 | 集體智慧程式設計      |       0.00 |  0.00 |   NULL |
|  8 | 統計學            |       0.00 |  0.00 |      1 |
|  9 | 多元統計分析      |       0.00 |  0.00 |      1 |
| 10 | 回歸分析          |       0.00 |  0.00 |      1 |
| 11 | 數學分析          |       0.00 |  0.00 |      2 |
| 12 | 高等代數          |       0.00 |  0.00 |      1 |
+----+-------------------+------------+-------+--------+
10 rows in set (0.00 sec)