VS2019 開發Django(四)------models


導航:VS2019開發Django系列

 

繼上篇我們匆匆遷移數據庫成功之后,又花了一個晚上研究了Django的模型,這里的模型其實就是ORM模型中的Entity,.Net里邊用的比較多的有Entity FrameworkSqlSugarNhibernate等等

1)字段類型,直接查看上一篇,我們的模型生成的表結構,找一下映射關系。從下面的數據可以看出來,

①表名稱是我們的app名稱hello下划線model類名稱question

②未指定主鍵的時候,默認創建了自增長的id主鍵

③外鍵生成字段的規則是模型屬性_id,下面的Choice類中的外鍵question屬性生成的外鍵字段是question_id,那么我們外鍵屬性命名的時候,一般直接命名為你需要關聯的那個類名

使用ForeignKey類型的時候,要傳遞你需要關聯的那個model為參數,並且一般主外鍵關系會設置級聯刪除

從模型和表結構的對比可以知道CharField->varchar,DateTimeField->datetime,IntegerField->int,這里就不一一說明了,有編程經驗的同學一看也就明白了

⑥發現一個問題,Choice中的votes屬性指定了默認值,但是在MySql中生成字段的時候,並未生效,我百度了一下,別人也遇到了這個問題,現在我還沒有找到解決辦法,先存疑,找到解決辦法之后再更新

 

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    def __str__(self):
        return self.question_text


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    def __str__(self):
        return self.choice_text
CREATE TABLE `hello_question` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `question_text` varchar(200) NOT NULL,
  `pub_date` datetime(6) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `hello_choice` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `choice_text` varchar(200) NOT NULL,
  `votes` int(11) NOT NULL,
  `question_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `hello_choice_question_id_8b790e13_fk_hello_question_id` (`question_id`),
  CONSTRAINT `hello_choice_question_id_8b790e13_fk_hello_question_id` FOREIGN KEY (`question_id`) REFERENCES `hello_question` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2)新建model,為我們之前開發的微信小程序中用到的C#實體在Django中添加model,先看Category類別與Menu菜單之間的關系:

/// <summary>
/// 分類
/// </summary>
public class Category
{
    /// <summary>
    /// 主鍵ID
    /// </summary>
    public int CategoryId { get; set; }

    /// <summary>
    /// 分類 類別名
    /// </summary>
    public string CategoryName { get; set; }

    /// <summary>
    /// 該類別下的菜單
    /// </summary>
    public List<Menu> Menus { get; set; }
}

/// <summary>
/// 菜單表
/// </summary>
public class Menu
{
    /// <summary>
    /// 菜單ID
    /// </summary>
    public int MenuId { get; set; }

    /// <summary>
    /// 類別ID
    /// </summary>
    public int CategoryId { get; set; }

    /// <summary>
    /// 菜單名
    /// </summary>
    public string MenuName { get; set; }

    /// <summary>
    /// 對應的圖片路徑
    /// </summary>
    public string ImgPath { get; set; }

    /// <summary>
    /// 單價
    /// </summary>
    public decimal Price { get; set; }
}

我們的Category類中會有多個Menu,但是每個Menu只屬於一個Category,這在關系型數據庫里邊叫做多對一關系,這種關系,在Django中怎么表示呢?其實就是一個外鍵關系,使用ForeignKey表示,另外就是我們的實體中有自己的主鍵,那么,自然不需要框架自動生成的那個id主鍵,我們可以使用primary_key來設置主鍵,使用AutoField來設置自增長,且看代碼:

#類別表
class Category(models.Model):
    category_id = models.AutoField(primary_key=True,verbose_name='類別ID')
    category_name = models.CharField(max_length=30,verbose_name='類別名')
    def __str__(self):
        return self.category_name
    class Meta:
        verbose_name_plural = '類別表'


#菜單表
class Menu(models.Model):
    menu_id = models.AutoField(primary_key=True,verbose_name='菜單ID')
    category = models.ForeignKey(Category,on_delete=models.CASCADE)
    menu_name = models.CharField(max_length=50,verbose_name='菜單名')
    img_path = models.CharField(max_length=100,verbose_name='圖片路徑',default='')
    price = models.DecimalField(max_digits=5, decimal_places=2)

 

再看Carts與Orders與Menu的關系:

/// <summary>
/// 購物車
/// </summary>
public class Carts
{
    /// <summary>
    /// 主鍵ID
    /// </summary>
    public int CartId { get; set; }

    /// <summary>
    /// 用戶ID
    /// </summary>
    public string OpenId { get; set; }

    /// <summary>
    /// 該用戶購物車中的清單
    /// </summary>
    public int MenuId { get; set; }
}

/// <summary>
/// 訂單
/// </summary>
public class Orders
{
    /// <summary>
    /// 訂單ID
    /// </summary>
    public int OrderId { get; set; }

    /// <summary>
    /// 用戶ID
    /// </summary>
    public string OpenId { get; set; }

    /// <summary>
    /// 該訂單包含的菜單
    /// </summary>
    public List<Menu> Menus { get; set; }

    /// <summary>
    /// 支付狀態
    /// </summary>
    public bool IsPaid { get; set; }

    /// <summary>
    /// 收貨地址
    /// </summary>
    public string Address { get; set; }

    /// <summary>
    /// 下單時間
    /// </summary>
    public DateTime OrderTime { get; set; }

    /// <summary>
    /// 支付時間
    /// </summary>
    public DateTime PayTime { get; set; }

    /// <summary>
    /// 總計
    /// </summary>
    public decimal TotalPrice { get { return this.Menus.Sum(x => x.Price); } }
}

從之前的設計來看,其實Carts與Menu是一對一的關系,因為最終購物車的呈現是以OpenId為查詢條件來呈現的。而訂單就不一樣了,訂單是以OrderId為查詢條件來呈現的,一個訂單中可以存在多個菜單,一個菜單可以屬於多個訂單,這種關系是屬於多對多的關系,那么這種關系在關系型數據庫中是怎么表示呢?關系型數據庫中要表達這種關系,一定會用到一個橋表,來做關聯,那么,Django中怎么表示多對多的關系呢?是不是也要新建一個橋表的模型呢?答案是否定的!Django提供了一ManyToManyField的類型來滿足這種關系,且看代碼:

#購物車
class Carts(models.Model):
    cart_id = models.AutoField(primary_key=True,verbose_name='購物車ID')
    open_id = models.CharField(max_length=50,verbose_name='')
    menu = models.ForeignKey(Menu,on_delete=models.CASCADE,default=0)


#訂單表
class Orders(models.Model):
    order_id = models.AutoField(primary_key=True)
    open_id = models.CharField(max_length=50,verbose_name='用戶ID')
    is_paid = models.BooleanField('是否已支付')
    address = models.CharField(max_length=100,verbose_name='收貨地址')
    order_time = models.DateTimeField(verbose_name='下單時間')
    pay_time = models.DateTimeField('支付時間')
    menus = models.ManyToManyField(Menu)

那么,我們到這里已經把模型建完了,剩下的就是遷移到數據庫中了,在項目文件上右鍵菜單,選擇Python,然后按K(Django進行遷移),然后再按M(Django遷移)等待完成。遷移成功之后,刷新我們數據庫中的表,有了!!!多對多關系,並且在多對多關系中,框架為我們自動創建了橋表。

3)總結

  • 該篇主要介紹Django中的實體對應於數據庫的映射關系,換句話說就是介紹了Django內置的ORM模型
  • 對比微信小程序中使用的C#實體,完成了Django中的實體映射,並執行了數據遷移。

今晚就到這里,待續......


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM