我的博客三|首頁後臺開發

聲明:本渣渣部分代碼參考自TendCode其實有不少代碼是不須要本身一行行碼出來,生產力是第一位。只有研究型人才須要生產代碼,做爲一名渣渣拿來用是最高效的作法。程序員都有一個開源的精神,碼出來的代碼自己是但願更多的人用到,應用到生產中。
參考編寫博客的 Model 與首頁面
整合資源也應該是一個碼農的必備能力,在實際生產中能夠更高效的工做html

項目環境

windows10
python==3.6.6
django==1.11.1

知識準備

首先本渣渣想對django項目結構作一下梳理,若是有的讀者對django不太熟悉,可能閱讀有障礙。
對django基礎作一下簡單瞭解。前端

推薦閱讀:vue

Django1.10 中文文檔python

大牛翻譯的django基礎部分mysql

簡單瞭解通用視圖git

開始 Django 開發以前,須要掌握如下知識:
• 建立 Django 工程,瞭解 Django 默認的工程目錄結構
• 建立 Django APP
• 理解 Django 的MTV 模式,學會編寫 Model、View、Template
• Django 如何處理靜態文件,即各類 CSS,JS,以及圖片文件等程序員

推薦閱讀:
我的博客-建立項目
Django中MVC與MVT設計模式github

Django的工做流程

一、 用戶經過瀏覽器輸入相應的 URL 發起 HTTP 請求(通常是 GET/POST)
用戶在網站前臺作的每次操做都是一次HTTP請求的觸發,經過觸發的URL,和後臺進行交互
2:Django後臺接收到請求,檢測 urls.py 文件,找到和用戶請求的URL 相匹配的項,而後調用該 URL 對應的視圖函數(view),在視圖內進行邏輯呈現,而後渲染數據到模板展現給用戶。redis

推薦閱讀:sql

靜態路由和動態路由

視圖函數被調用後,可能會訪問數據庫(Model)去查詢用戶想要請求的數據,並加載模板文件(Template),渲染完數據後打包成 HttpResponse 返回給瀏覽器(Http協議)

從流程能夠看出,開發者須要作的事情以下:
• 編寫相應的 url
• 編寫數據庫(Model)
• 編寫處理 Http 請求的視圖函數(View)
• 編寫須要渲染數據的模板(Template)

下面遵循這樣的開發流程繼續進行咱們我的博客的開發:

雖然博客站點的django項目已經爛大街了,可是不少人還沒意識到我的博客的價值,有時間咱們能夠談談這個問題。

初版選擇使用Django通用視圖開發,後續升級先後端分離開發(正在學習中)

推薦閱讀:

Django通用視圖

ListView 和 DetailView

在接觸到django到如今看到的教程大都沒有采用django的通用視圖,可是爲了更好的認識django,在這裏本渣渣,想嘗試儘可能在開發博客主體時使用通用視圖

爲何選擇使用通用視圖

一、 目前在看到的django教程中大部分都未使用通用視圖,頂可能是繼承通用類。這樣你就沒辦法真正瞭解django框架,django獨特之處就在於構建Web應用程序的經常使用功能已經在框架內,而不是單獨的庫。通用視圖是Django爲解決建站過程當中的常見的呈現模式而創建的
通用視圖使用原則
代碼越少越好
永遠不要重複代碼
view應當只呈現邏輯, 不該包含業務邏輯
保持view邏輯清晰簡單
二、 鍛鍊快速高效開發一類網站的能力
瞭解了通用視圖你能夠快速開發一類網站好比博客、論壇都有類似的需求

三、 組合方便
這裏本渣渣的作法是扒取崔慶才我的博客前端源碼,而後經過django實現網站後端開發,使用django 通用視圖,能夠縮短開發週期,並且可以具有使用django快速模仿一個網站的能力

下面不廢話開幹

按流程來,規範的流程少出錯,嚴謹應該是一個碼農的素養
目前項目文件結構

項目結構

一、前端

抓取崔慶才我的博客網站前端源碼一文中抓取的崔慶才博客前端源碼放入我的博客-建立項目一文中建立的項目中
https://www.jianshu.com/p/246...

二、配置基本信息

設置blog/settings.py
添加 apps 目錄

sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))

settings.py

添加app

# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    'storm',
]

添加app

添加模板

ROOT_URLCONF = 'blog.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],  # 設置視圖
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

添加模板

鏈接數據庫,首先要在本地數據庫建立名爲blog的數據庫
這裏須要用到數據庫鏈接包,
請參考安裝python包到虛擬環境安裝包
Name: mysqlclient
Version: 1.4.2.post1

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': 'localhost',
        'PORT': '3306',
        'USER': 'root',
        'PASSWORD': 'root',
        'NAME': 'blog',
        # 若是建立的數據庫是uft-8編碼,映射數據庫時出現警告,添加此行解決問題
        'OPTIONS': {
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
            'charset': 'utf8mb4',
        },
    }
}

鏈接數據庫

配置靜態文件路徑

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

三、model.py編寫

針對blog開發大致有這幾個通用的models類

文章、幻燈片、文章標籤、文章分類、友情連接

這裏爲了後期可以更好的給本站作SEO優化,這裏添加了一個,文章關鍵詞,死鏈

文章、幻燈片、文章標籤、文章分類、友情連接、關鍵詞、死鏈

因而可知,設計數據庫結構就是編寫 models,數據庫中每個實體對應的表在 django 中對用着 models.py 中的一個類,類的屬性對應着數據庫表的屬性列。

# 文章關鍵詞,用來做爲SEO中keywords
class Keyword(models.Model):
    name = models.CharField('文章關鍵詞', max_length=20)

    class Meta:
        verbose_name = '關鍵詞'
        verbose_name_plural = verbose_name
        ordering = ['name']

    def __str__(self):
        return self.name


# 文章標籤
class Tag(models.Model):
    name = models.CharField('文章標籤', max_length=20)
    slug = models.SlugField(unique=True)
    description = models.TextField('描述', max_length=240, default=settings.SITE_DESCRIPTION,
                                   help_text='用來做爲SEO中description,長度參考SEO標準')

    class Meta:
        verbose_name = '標籤'
        verbose_name_plural = verbose_name
        ordering = ['id']

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('blog:tag', kwargs={'slug': self.slug})

    def get_article_list(self):
        '''返回當前標籤下全部發表的文章列表'''
        return Article.objects.filter(tags=self)


# 文章分類
class Category(models.Model):
    name = models.CharField('文章分類', max_length=20)
    slug = models.SlugField(unique=True)
    description = models.TextField('描述', max_length=240, default=settings.SITE_DESCRIPTION,
                                   help_text='用來做爲SEO中description,長度參考SEO標準')

    class Meta:
        verbose_name = '分類'
        verbose_name_plural = verbose_name
        ordering = ['name']

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('blog:category', kwargs={'slug': self.slug})

    def get_article_list(self):
        return Article.objects.filter(category=self)


# 文章
class Article(models.Model):

    # 文章縮略圖
    IMG_LINK = '/static/img/summary.png'
    
    author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='做者')
    
    # 文章標題,CharField 表示對應數據庫中數據表的列的數據類型,'標題'是一個位置參數     
    #(verbose_name),主要用於 django 的後臺系統。max_length 表示能存儲的字符串    
    # 的最大長度
    title = models.CharField(max_length=150, verbose_name='文章標題')
    
    # 這裏填的內容有助於後期SEO優化
    summary = models.TextField('文章摘要', max_length=230, default='文章摘要等同於網頁description內容,請務必填寫...')
    
    # 文章正文,TextField 用來存儲大文本字符
    body = models.TextField(verbose_name='文章內容')
    
    # 文章縮略圖地址
    img_link = models.CharField('圖片地址', default=IMG_LINK, max_length=255)
    
     # 文章建立時間,DateTimeField用於存儲時間,設定auto_now_add參數爲真,則在文章被建立時會自動添加建立時間
    create_date = models.DateTimeField(verbose_name='建立時間', auto_now_add=True)
    
    # 文章最後一次編輯時間,auto_now=True表示每次修改文章時自動添加修改的時間
    update_date = models.DateTimeField(verbose_name='修改時間', auto_now=True)
    
    # 閱覽量,PositiveIntegerField存儲非負整數
    # views = models.PositiveIntegerField('閱覽量', default=0)
    views = models.IntegerField('閱覽量', default=0)
    
    slug = models.SlugField(unique=True)

# 文章的分類,ForeignKey即數據庫中的外鍵。外鍵的定義是:若是數據庫中某個表的列的值是另一個表的主鍵。外鍵定義了一個一對多的關係,這裏即一篇文章對應一個分類,而一個分類下可能有多篇文章。詳情參考django官方文檔關於ForeinKey的說明,on_delete=models.SET_NULL表示刪除某個分類(category)後該分類下全部的Article的外鍵設爲null(空)

    category = models.ForeignKey(Category, verbose_name='文章分類',on_delete=models.SET_NULL)
    tags = models.ManyToManyField(Tag, verbose_name='標籤')
    
    keywords = models.ManyToManyField(Keyword, verbose_name='文章關鍵詞',
                                      help_text='文章關鍵詞,用來做爲SEO中keywords,最好使用長尾詞,3-4個足夠')
    
    def __str__(self):
        # 主要用於交互解釋器顯示錶示該類的字符串
        return self.title

    class Meta:
        verbose_name = '文章'
        verbose_name_plural = verbose_name
        ordering = ['-create_date']


# 幻燈片
class Carousel(models.Model):
    number = models.IntegerField('編號', help_text='編號決定圖片播放的順序,圖片不要多於5張')
    title = models.CharField('標題', max_length=20, blank=True, null=True, help_text='標題能夠爲空')
    content = models.CharField('描述', max_length=80)
    img_url = models.CharField('圖片地址', max_length=200)
    url = models.CharField('跳轉連接', max_length=200, default='#', help_text='圖片跳轉的超連接,默認#表示不跳轉')

    class Meta:
        verbose_name = '圖片輪播'
        verbose_name_plural = verbose_name
        # 編號越小越靠前,添加的時間越晚越靠前
        ordering = ['number', '-id']

    def __str__(self):
        return self.content[:25]


# 死鏈
class Silian(models.Model):
    badurl = models.CharField('死鏈地址', max_length=200, help_text='注意:地址是以http開頭的完整連接格式')
    remark = models.CharField('死鏈說明', max_length=50, blank=True, null=True)
    add_date = models.DateTimeField('提交日期', auto_now_add=True)

    class Meta:
        verbose_name = '死鏈'
        verbose_name_plural = verbose_name
        ordering = ['-add_date']

    def __str__(self):
        return self.badurl


class FriendLink(models.Model):
    name = models.CharField('網站名稱', max_length=50)
    description = models.CharField('網站描述', max_length=100, blank=True)
    link = models.URLField('友鏈地址', help_text='請填寫http或https開頭的完整形式地址')
    logo = models.URLField('網站LOGO', help_text='請填寫http或https開頭的完整形式地址', blank=True)
    create_date = models.DateTimeField('建立時間', auto_now_add=True)
    is_active = models.BooleanField('是否有效', default=True)
    is_show = models.BooleanField('是否首頁展現', default=False)

    class Meta:
        verbose_name = '友情連接'
        verbose_name_plural = verbose_name
        ordering = ['create_date']

    def __str__(self):
        return self.name

    def get_home_url(self):
        '''提取友鏈的主頁'''
        u = re.findall(r'(http|https://.*?)/.*?', self.link)
        home_url = u[0] if u else self.link
        return home_url

    def active_to_false(self):
        self.is_active = False
        self.save(update_fields=['is_active'])

    def show_to_false(self):
        self.is_show = True
        self.save(update_fields=['is_show'])

model 定義完畢後,運行如下命令便可生成相應的數據庫表:

python manage.py makemigrations
python manage.py migrate

針對models分別給出如下參考資料供學習:

Models:
官方文檔
Django1.10 中文文檔
大牛翻譯

推薦學習:
自強學堂
Django的ORM映射機制與數據庫實戰
數據庫模型(Models)對象映射表ORM

field(字段選項):
官方文檔
我的技術博文

ForeinKey(一對多)、ManyToMany(多對多)、OneToOne(一對一):
官方文檔
Django的ORM映射機制與數據庫實戰

四、View編寫

上面已經介紹了 django 應用的工做流程,數據庫創建完畢後須要編寫視圖函數(view)來處理 Http 請求。一樣先來看 django 的 view 代碼是如何寫的,這裏數據庫內沒有文章先不作文章展現邏輯編寫,待後續一一進行,這裏只寫一個視圖讓首頁能夠被訪問。

視圖代碼

from django.views import generic
from django.conf import settings
from .models import Article, Tag, Category, Timeline, Silian


# Create your views here.
class IndexView(generic.ListView):
    """
        首頁視圖,繼承自ListVIew,用於展現從數據庫中獲取的文章列表
    """
    
    # 獲取數據庫中的文章列表
    model = Article
    
    # template_name屬性用於指定使用哪一個模板進行渲染
    template_name = 'index.html'
    
    # context_object_name屬性用於給上下文變量取名(在模板中使用該名字)
    context_object_name = 'articles'

五、配置路由

blog/urls.py

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    # allauth
    url(r'^accounts/', include('allauth.urls')),

    # storm
    url('', include('storm.urls', namespace='blog')),  # blog
]

apps/storm/urls.py

# ---------------------------
__author__ = 'stormsha'
__date__ = '2019/2/20 23:27'
# ---------------------------

from django.conf.urls import url
# from .views import goview
from .views import IndexView

urlpatterns = [

    url(r'^$', IndexView.as_view(), name='index'),  # 主頁,天然排序

]

六、運行效果

運行效果
如今首頁流程基本走通之,差視圖內的邏輯、和數據渲染的問題了,靜待後續。

七、總結

本渣渣也是在繁忙的工做之餘,抽出點時間想本身搞一下博客,可是不想草草了事,想從這個項目中實踐以下知識

抓取網站前端頁面源碼、Django通用視圖、django rest framework、vue.js、redis數據緩存、docker容器部署、git、SEO技術

錢途:想法——實現——部署——運營——維護——盈利

有什麼問題歡迎留言,或者關注微信公衆號「stormsha」進行深度技術、思惟碰撞交流。

相關文章
相關標籤/搜索