聲明:本渣渣部分代碼參考自TendCode其實(shí)有很多代碼是不需要自己一行行碼出來邢羔,生產(chǎn)力是第一位桑孩。只有研究型人才需要生產(chǎn)代碼流椒,作為一名渣渣拿來用是最高效的做法。程序員都有一個開源的精神温数,碼出來的代碼本身是希望更多的人用到蜻势,應(yīng)用到生產(chǎn)中握玛。
參考編寫博客的 Model 與首頁面
整合資源也應(yīng)該是一個碼農(nóng)的必備能力挠铲,在實(shí)際生產(chǎn)中可以更高效的工作
項(xiàng)目環(huán)境
windows10
python==3.6.6
django==1.11.1
首先本渣渣想對django項(xiàng)目結(jié)構(gòu)做一下梳理拂苹,如果有的讀者對django不太熟悉,可能閱讀有障礙浴韭。
對django基礎(chǔ)做一下簡單了解囱桨。
推薦閱讀:
開始 Django 開發(fā)之前,需要掌握以下知識:
? 創(chuàng)建 Django 工程窘面,了解 Django 默認(rèn)的工程目錄結(jié)構(gòu)
? 創(chuàng)建 Django APP
? 理解 Django 的MTV 模式财边,學(xué)會編寫 Model点骑、View黑滴、Template
? Django 如何處理靜態(tài)文件袁辈,即各種 CSS,JS媳危,以及圖片文件等
推薦閱讀:
個人博客-創(chuàng)建項(xiàng)目
Django中MVC與MVT設(shè)計(jì)模式
Django的工作流程
1待笑、 用戶通過瀏覽器輸入相應(yīng)的 URL 發(fā)起 HTTP 請求(一般是 GET/POST)
用戶在網(wǎng)站前臺做的每次操作都是一次HTTP請求的觸發(fā)莺债,通過觸發(fā)的URL齐邦,和后臺進(jìn)行交互
2:Django后臺接收到請求,檢測 urls.py 文件措拇,找到和用戶請求的URL 相匹配的項(xiàng)丐吓,然后調(diào)用該 URL 對應(yīng)的視圖函數(shù)(view)券犁,在視圖內(nèi)進(jìn)行邏輯呈現(xiàn)粘衬,然后渲染數(shù)據(jù)到模板展示給用戶。
推薦閱讀:
視圖函數(shù)被調(diào)用后勘伺,可能會訪問數(shù)據(jù)庫(Model)去查詢用戶想要請求的數(shù)據(jù)褂删,并加載模板文件(Template)飞醉,渲染完數(shù)據(jù)后打包成 HttpResponse 返回給瀏覽器(Http協(xié)議)
從流程可以看出,開發(fā)者需要做的事情如下:
? 編寫相應(yīng)的 url
? 編寫數(shù)據(jù)庫(Model)
? 編寫處理 Http 請求的視圖函數(shù)(View)
? 編寫需要渲染數(shù)據(jù)的模板(Template)
下面遵循這樣的開發(fā)流程繼續(xù)進(jìn)行我們個人博客的開發(fā):
雖然博客站點(diǎn)的django項(xiàng)目已經(jīng)爛大街了屯阀,但是很多人還沒意識到個人博客的價值缅帘,有時間我們可以談?wù)勥@個問題。
第一版選擇使用Django通用視圖開發(fā)难衰,后續(xù)升級前后端分離開發(fā)(正在學(xué)習(xí)中)
推薦閱讀:
在接觸到django到現(xiàn)在看到的教程大都沒有采用django的通用視圖钦无,但是為了更好的認(rèn)識django,在這里本渣渣召衔,想嘗試盡量在開發(fā)博客主體時使用通用視圖
為什么選擇使用通用視圖
1、 目前在看到的django教程中大部分都未使用通用視圖,頂多是繼承通用類趣席。這樣你就沒辦法真正了解django框架兵志,django獨(dú)特之處就在于構(gòu)建Web應(yīng)用程序的常用功能已經(jīng)在框架內(nèi),而不是單獨(dú)的庫宣肚。通用視圖是Django為解決建站過程中的常見的呈現(xiàn)模式而建立的
通用視圖使用原則
代碼越少越好
永遠(yuǎn)不要重復(fù)代碼
view應(yīng)當(dāng)只呈現(xiàn)邏輯, 不應(yīng)包含業(yè)務(wù)邏輯
保持view邏輯清晰簡單
2想罕、 鍛煉快速高效開發(fā)一類網(wǎng)站的能力
了解了通用視圖你可以快速開發(fā)一類網(wǎng)站比如博客、論壇都有相似的需求
3霉涨、 組合方便
這里本渣渣的做法是扒取崔慶才個人博客前端源碼按价,然后通過django實(shí)現(xiàn)網(wǎng)站后端開發(fā),使用django 通用視圖笙瑟,可以縮短開發(fā)周期楼镐,而且能夠具備使用django快速模仿一個網(wǎng)站的能力
下面不廢話開干
按流程來,規(guī)范的流程少出錯往枷,嚴(yán)謹(jǐn)應(yīng)該是一個碼農(nóng)的素養(yǎng)
目前項(xiàng)目文件結(jié)構(gòu)
1框产、前端
把抓取崔慶才個人博客網(wǎng)站前端源碼一文中抓取的崔慶才博客前端源碼放入個人博客-創(chuàng)建項(xiàng)目一文中創(chuàng)建的項(xiàng)目中
http://www.reibang.com/p/24648705d9bd
2、配置基本信息
設(shè)置blog/settings.py
添加 apps 目錄
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
添加app
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'storm',
]
添加模板
ROOT_URLCONF = 'blog.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], # 設(shè)置視圖
'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',
],
},
},
]
連接數(shù)據(jù)庫错洁,首先要在本地?cái)?shù)據(jù)庫創(chuàng)建名為blog的數(shù)據(jù)庫
這里需要用到數(shù)據(jù)庫連接包秉宿,
請參考安裝python包到虛擬環(huán)境安裝包
Name: mysqlclient
Version: 1.4.2.post1
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': 'localhost',
'PORT': '3306',
'USER': 'root',
'PASSWORD': 'root',
'NAME': 'blog',
# 如果創(chuàng)建的數(shù)據(jù)庫是uft-8編碼,映射數(shù)據(jù)庫時出現(xiàn)警告,添加此行解決問題
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
'charset': 'utf8mb4',
},
}
}
配置靜態(tài)文件路徑
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
model.py編寫
針對blog開發(fā)大體有這幾個通用的models類
文章屯碴、幻燈片描睦、文章標(biāo)簽、文章分類导而、友情鏈接
這里為了后期能夠更好的給本站做SEO優(yōu)化忱叭,這里添加了一個,文章關(guān)鍵詞嗡载,死鏈
文章窑多、幻燈片仍稀、文章標(biāo)簽洼滚、文章分類、友情鏈接技潘、關(guān)鍵詞遥巴、死鏈
由此可見,設(shè)計(jì)數(shù)據(jù)庫結(jié)構(gòu)就是編寫 models享幽,數(shù)據(jù)庫中每一個實(shí)體對應(yīng)的表在 django 中對用著 models.py 中的一個類铲掐,類的屬性對應(yīng)著數(shù)據(jù)庫表的屬性列。
# 文章關(guān)鍵詞值桩,用來作為SEO中keywords
class Keyword(models.Model):
name = models.CharField('文章關(guān)鍵詞', max_length=20)
class Meta:
verbose_name = '關(guān)鍵詞'
verbose_name_plural = verbose_name
ordering = ['name']
def __str__(self):
return self.name
# 文章標(biāo)簽
class Tag(models.Model):
name = models.CharField('文章標(biāo)簽', max_length=20)
slug = models.SlugField(unique=True)
description = models.TextField('描述', max_length=240, default=settings.SITE_DESCRIPTION,
help_text='用來作為SEO中description,長度參考SEO標(biāo)準(zhǔn)')
class Meta:
verbose_name = '標(biāo)簽'
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):
'''返回當(dāng)前標(biāo)簽下所有發(fā)表的文章列表'''
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標(biāo)準(zhǔn)')
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='作者')
# 文章標(biāo)題摆霉,CharField 表示對應(yīng)數(shù)據(jù)庫中數(shù)據(jù)表的列的數(shù)據(jù)類型,'標(biāo)題'是一個位置參數(shù)
#(verbose_name),主要用于 django 的后臺系統(tǒng)携栋。max_length 表示能存儲的字符串
# 的最大長度
title = models.CharField(max_length=150, verbose_name='文章標(biāo)題')
# 這里填的內(nèi)容有助于后期SEO優(yōu)化
summary = models.TextField('文章摘要', max_length=230, default='文章摘要等同于網(wǎng)頁description內(nèi)容搭盾,請務(wù)必填寫...')
# 文章正文,TextField 用來存儲大文本字符
body = models.TextField(verbose_name='文章內(nèi)容')
# 文章縮略圖地址
img_link = models.CharField('圖片地址', default=IMG_LINK, max_length=255)
# 文章創(chuàng)建時間婉支,DateTimeField用于存儲時間鸯隅,設(shè)定auto_now_add參數(shù)為真,則在文章被創(chuàng)建時會自動添加創(chuàng)建時間
create_date = models.DateTimeField(verbose_name='創(chuàng)建時間', auto_now_add=True)
# 文章最后一次編輯時間向挖,auto_now=True表示每次修改文章時自動添加修改的時間
update_date = models.DateTimeField(verbose_name='修改時間', auto_now=True)
# 閱覽量蝌以,PositiveIntegerField存儲非負(fù)整數(shù)
# views = models.PositiveIntegerField('閱覽量', default=0)
views = models.IntegerField('閱覽量', default=0)
slug = models.SlugField(unique=True)
# 文章的分類,F(xiàn)oreignKey即數(shù)據(jù)庫中的外鍵何之。外鍵的定義是:如果數(shù)據(jù)庫中某個表的列的值是另外一個表的主鍵跟畅。外鍵定義了一個一對多的關(guān)系,這里即一篇文章對應(yīng)一個分類溶推,而一個分類下可能有多篇文章碍彭。詳情參考django官方文檔關(guān)于ForeinKey的說明,on_delete=models.SET_NULL表示刪除某個分類(category)后該分類下所有的Article的外鍵設(shè)為null(空)
category = models.ForeignKey(Category, verbose_name='文章分類',on_delete=models.SET_NULL)
tags = models.ManyToManyField(Tag, verbose_name='標(biāo)簽')
keywords = models.ManyToManyField(Keyword, verbose_name='文章關(guān)鍵詞',
help_text='文章關(guān)鍵詞悼潭,用來作為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('標(biāo)題', max_length=20, blank=True, null=True, help_text='標(biāo)題可以為空')
content = models.CharField('描述', max_length=80)
img_url = models.CharField('圖片地址', max_length=200)
url = models.CharField('跳轉(zhuǎn)鏈接', max_length=200, default='#', help_text='圖片跳轉(zhuǎn)的超鏈接皆疹,默認(rèn)#表示不跳轉(zhuǎn)')
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('網(wǎng)站名稱', max_length=50)
description = models.CharField('網(wǎng)站描述', max_length=100, blank=True)
link = models.URLField('友鏈地址', help_text='請?zhí)顚慼ttp或https開頭的完整形式地址')
logo = models.URLField('網(wǎng)站LOGO', help_text='請?zhí)顚慼ttp或https開頭的完整形式地址', blank=True)
create_date = models.DateTimeField('創(chuàng)建時間', 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 定義完畢后占拍,運(yùn)行以下命令即可生成相應(yīng)的數(shù)據(jù)庫表:
python manage.py makemigrations
python manage.py migrate
針對models分別給出以下參考資料供學(xué)習(xí):
Models:
官方文檔
Django1.10 中文文檔
大牛翻譯
推薦學(xué)習(xí):
自強(qiáng)學(xué)堂
Django的ORM映射機(jī)制與數(shù)據(jù)庫實(shí)戰(zhàn)
數(shù)據(jù)庫模型(Models)對象映射表ORM
field(字段選項(xiàng)):
官方文檔
個人技術(shù)博文
ForeinKey(一對多)略就、ManyToMany(多對多)、OneToOne(一對一):
官方文檔
Django的ORM映射機(jī)制與數(shù)據(jù)庫實(shí)戰(zhàn)
View編寫
上面已經(jīng)介紹了 django 應(yīng)用的工作流程晃酒,數(shù)據(jù)庫建立完畢后需要編寫視圖函數(shù)(view)來處理 Http 請求表牢。同樣先來看 django 的 view 代碼是如何寫的,這里數(shù)據(jù)庫內(nèi)沒有文章先不做文章展示邏輯編寫贝次,待后續(xù)一一進(jìn)行崔兴,這里只寫一個視圖讓首頁可以被訪問。
視圖代碼
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蛔翅,用于展示從數(shù)據(jù)庫中獲取的文章列表
"""
# 獲取數(shù)據(jù)庫中的文章列表
model = Article
# template_name屬性用于指定使用哪個模板進(jìn)行渲染
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'), # 主頁敲茄,自然排序
]
運(yùn)行效果
現(xiàn)在首頁流程基本走通之,差視圖內(nèi)的邏輯山析、和數(shù)據(jù)渲染的問題了堰燎,靜待后續(xù)。
總結(jié)
本渣渣也是在繁忙的工作至于笋轨,抽出點(diǎn)時間想自己搞一下博客秆剪,但是不想草草了事赊淑,想從這個項(xiàng)目中實(shí)踐如下知識
抓取網(wǎng)站前端頁面源碼、Django通用視圖仅讽、django rest framework膏燃、vue.js、redis數(shù)據(jù)緩存何什、docker容器部署组哩、git、SEO技術(shù)
錢途:想法——實(shí)現(xiàn)——部署——運(yùn)營——維護(hù)——盈利