02 | 編寫Model層程式碼

An楠發表於2019-08-02

按照上節課的結構整理完專案之後,我們來建立Model層程式碼,不過在此之前,我們先來看下之前整理的Model需要的模型和欄位:

文章:
- id
- 標題
- 作者
- 分類(多對一)
- 標籤(多對多)
- 摘要
- 正文
- 狀態
- 釋出時間

分類:
- id
- 名稱
- 狀態
- 作者
- 建立時間
- 是否置頂導航

標籤:
- id
- 名稱
- 狀態
- 作者
- 建立時間

友鏈:
- id
- 網站名稱
- 連結
- 作者
- 狀態
- 建立時間
- 權重

評論:
- id
- 文章(多對一)
- 使用者名稱
- 郵箱
- 網站地址
- 內容
- 建立時間
- 作者

側欄:
- id
- 標題
- 型別(最新文章/最熱文章/最近評論/內容)
- 內容
- 建立時間
- 作者

建立APP

Blog App

在建立Model之前,我們先需要建立app,在Django中是通過app的模式來管理不同業務模組的程式碼的。我們先建立一個blog的app,進入上節我們建立好的專案中cd typeidea/typeidea。執行: ./manage.py startapp blog。此時我們得到現在的結構:

.
├── CHANGELOG.md
├── LICENSE
├── README.md
├── requirements.txt
└── typeidea
    ├── blog
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── manage.py
    └── typeidea
        ├── __init__.py
        ├── settings
        │   ├── __init__.py
        │   ├── base.py
        │   └── develop.py
        ├── urls.py
        └── wsgi.py

現在我們來編寫blog/models.py中的程式碼,根據我們一開始列出的模型,我們先建立部落格內容相關的模型:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.contrib.auth.models import User
from django.db import models


class Category(models.Model):
    STATUS_ITEMS = (
        (1, '正常'),
        (2, '刪除'),
    )

    name = models.CharField(max_length=50, verbose_name="名稱")
    status = models.PositiveIntegerField(default=1, choices=STATUS_ITEMS, verbose_name="狀態")
    is_nav = models.BooleanField(default=False, verbose_name="是否為導航")

    owner = models.ForeignKey(User, verbose_name="作者")
    created_time = models.DateTimeField(auto_now_add=True, verbose_name="建立時間")

    class Meta:
        verbose_name = verbose_name_plural = '分類'


class Tag(models.Model):
    STATUS_ITEMS = (
        (1, '正常'),
        (2, '刪除'),
    )

    name = models.CharField(max_length=10, verbose_name="名稱")
    status = models.PositiveIntegerField(default=1, choices=STATUS_ITEMS, verbose_name="狀態")

    owner = models.ForeignKey(User, verbose_name="作者")
    created_time = models.DateTimeField(auto_now_add=True, verbose_name="建立時間")

    class Meta:
        verbose_name = verbose_name_plural = '標籤'


class Post(models.Model):
    STATUS_ITEMS = (
        (1, '正常'),
        (2, '刪除'),
        (3, '草稿'),
    )

    title = models.CharField(max_length=255, verbose_name="標題")
    desc = models.CharField(max_length=1024, blank=True, verbose_name="摘要")
    content = models.TextField(verbose_name="正文", help_text="正文必須為MarkDown格式")
        status = models.PositiveIntegerField(default=1, choices=STATUS_ITEMS, verbose_name="狀態")
    category = models.ForeignKey(Category, verbose_name="分類")
    tag = models.ManyToManyField(Tag, verbose_name="標籤")

    owner = models.ForeignKey(User, verbose_name="作者")
    created_time = models.DateTimeField(auto_now_add=True, verbose_name="建立時間")

    class Meta:
        verbose_name = verbose_name_plural = "文章"

這幾個Model都是跟內容直接相關的,因此我們把他們放到一個APP中,其他的Model我們接下來再做拆分。

對於其中的models.CharField或者models.TextField你可能有些疑惑,這些型別就是我們這個模型中欄位的型別。比如CharFieldTextField分別對應資料庫中不同的型別,其他的也類似,後面我們會詳細解釋。Model以及欄位型別一起構成了ORM。

config app

接下來我們來建立另外一個Django的app,用來放置其他的幾個模型,前面那個blogapp是用來放內容相關的資料,這個用來放配置相關的資料——側邊欄和友鏈。

我們首先啟用虛擬環境: workon typeidea-env, 然後進入typeidea/typeidea目錄下,執行./manage.py startapp config。現在整體目錄結構如下:

.
├── CHANGELOG.md
├── LICENSE
├── README.md
├── requirements.txt
└── typeidea
    ├── blog
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── config
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── manage.py
    └── typeidea
        ├── __init__.py
        ├── settings
        │   ├── __init__.py
        │   ├── base.py
        │   └── develop.py
        ├── urls.py
        └── wsgi.py

接下來來編寫config/models.py中的程式碼:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.contrib.auth.models import User
from django.db import models


class Link(models.Model):
    STATUS_ITEMS = (
        (1, '正常'),
        (2, '刪除'),
    )
    title = models.CharField(max_length=50, verbose_name="標題")
    href = models.URLField(verbose_name="連結")  # 預設長度200
    status = models.PositiveIntegerField(default=1, choices=STATUS_ITEMS, verbose_name="狀態")
    weight = models.PositiveIntegerField(default=1, choices=zip(range(1, 6), range(1, 6)),
                                         verbose_name="權重",
                                         help_text="權重越高展示順序約靠前")

    owner = models.ForeignKey(User, verbose_name="作者")
    created_time = models.DateTimeField(auto_now_add=True, verbose_name="建立時間")

    class Meta:
        verbose_name = verbose_name_plural = "友鏈"


class SideBar(models.Model):
    STATUS_ITEMS = (
        (1, '展示'),
        (2, '下線'),
    )
    SIDE_TYPE = (
        (1, 'HTML'),
        (2, '最新文章'),
        (3, '最熱文章'),
        (4, '最近評論'),
    )
    title = models.CharField(max_length=50, verbose_name="標題")
    display_type = models.PositiveIntegerField(default=1, choices=SIDE_TYPE,
                                               verbose_name="展示型別")
    content = models.CharField(max_length=500, blank=True, verbose_name="內容",
                               help_text="如果設定的不是HTML型別,可為空")

    owner = models.ForeignKey(User, verbose_name="作者")
    created_time = models.DateTimeField(auto_now_add=True, verbose_name="建立時間")

    class Meta:
        verbose_name = verbose_name_plural = "側邊欄"

配置部分的功能暫時如此,後面我們會在其中加入更多的配置。這些來源於後續的需求。任何一款產品,都不是一蹴而就的,都是經過不斷的迭代,不斷的調整才形成最後或者說比較合適的形態。而對我們技術人員來說,需要做的就是理解產品是不斷變化的,然後提供相應的技術支援。

最後,我們來建立評論部分,這部分我們單獨拎出來。因為評論可以是完全獨立的模組,我們可以把它耦合到文章上,建立個一對多的關係。我們也可以做的鬆耦合一點,評論只關心評論的頁面,也就是當前評論的URL,這樣的好處是,產品要增加新的頁面型別,比如友鏈頁增加評論,或者文章列表頁增加評論,都可以,只關心URL,而不用關心要評論的物件是什麼。

comment app

同上面一樣,建立comment的app,想必你應該輕車熟路了,就不多說了。建立好app之後,我們編寫model.py中的程式碼。

相關文章