一、搞清楚需求(產品經理)
(1)基於用戶認證組件和Ajax實現登錄驗證(圖片驗證碼)
(2)基於forms組件和Ajax實現注冊功能
(3)設計系統首頁(文章列表渲染)
(4)設計個人站點頁面(跨表查詢、分組查詢)
(5)文章詳情頁
(6)實現文章點贊功能(Ajax)
(7)實現文章評論功能:涉及文章的評論和評論的評論
(8)富文本編輯框和防止xss攻擊
二、設計博客園表結構
博客系統表結構流程圖
流程圖地址:https://www.processon.com/diagraming/5b529154e4b0f8477d8d0d9d

三、創建項目與遷移表
1、根據表結構圖在models.py中創建模型
from django.db import models
# Create your models here.
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
"""
用戶信息表:
使用用戶認證組件,用戶表的字段不夠用,需要繼承AbstractUser類來定制一個自己的用戶表。
在繼承后,不再生成auth_user表,直接使用user_info表
"""
nid = models.AutoField(primary_key=True)
telephone = models.CharField(max_length=11, null=True, unique=True)
avatar = models.FileField(upload_to='avatars/', default="/avatars/default.png") # 該字段存放每個用戶的頭像文件
create_time = models.DateTimeField(verbose_name='創建時間', auto_now_add=True) # auto_now_add字段:這個創建時間不用賦值,默認用當前時間賦值
blog = models.OneToOneField(to='Blog', to_field='nid', null=True, on_delete=models.CASCADE) # 站點表和用戶表一對一關系
def __str__(self):
return self.username
class Blog(models.Model):
"""
博客信息表(站點)
用戶和站點一對一關系,
"""
nid = models.AutoField(primary_key=True)
title = models.CharField(verbose_name='個人博客標題', max_length=64)
site_name = models.CharField(verbose_name='站點名稱', max_length=64)
theme = models.CharField(verbose_name='博客主題', max_length=32)
def __str__(self):
return self.title
class Category(models.Model):
"""
博主個人文章分類表:Linux、python、面試心得、雞湯
分類表和用戶表是多對一的關系,由於用戶和站點是一對一,分類表與站點也是多對一的關系
"""
nid = models.AutoField(primary_key=True)
title = models.CharField(verbose_name='分類標題', max_length=32)
blog = models.ForeignKey(verbose_name='所屬博客', to='Blog', to_field='nid', on_delete=models.CASCADE)
def __str__(self):
return self.title
class Tag(models.Model):
"""
標簽
站點和標簽綁定的是一對多的關系
"""
nid = models.AutoField(primary_key=True)
title = models.CharField(verbose_name='標簽名稱', max_length=32)
blog = models.ForeignKey(verbose_name='所屬博客', to='Blog', to_field='nid', on_delete=models.CASCADE)
def __str__(self):
return self.title
class Article(models.Model):
"""
文章表
分類和文章的關系在這里設置為一對多關系(為了與文章和標簽關系形成區分)
用戶和文章是一對多的關系
標簽與文章是多對多的關系(用中介模型創建第三張表)
"""
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=50, verbose_name='文章標題')
desc = models.CharField(max_length=255, verbose_name='文章描述') # 摘要
create_time = models.DateTimeField(verbose_name='創建時間', auto_now_add=True) # 發布時間
content = models.TextField() # 文章內容
# comment_count = models.IntegerField(default=0)
# up_count = models.IntegerField(default=0)
# down_count = models.IntegerField(default=0)
user = models.ForeignKey(verbose_name='作者', to='UserInfo', to_field='nid', on_delete=models.CASCADE)
category = models.ForeignKey(to='Category', to_field='nid', null=True, on_delete=models.CASCADE)
tags = models.ManyToManyField( # 中介模型創建第三張關系表
to="Tag",
through='Article2Tag',
through_fields=('article', 'tag'),
)
def __str__(self):
return self.title
class Article2Tag(models.Model):
"""
文章和標簽關系表
"""
nid = models.AutoField(primary_key=True)
article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid', on_delete=models.CASCADE)
tag = models.ForeignKey(verbose_name='標簽', to="Tag", to_field='nid', on_delete=models.CASCADE)
class Meta:
unique_together = [ # 聯合唯一,兩個字段不能重復
('article', 'tag'),
]
def __str__(self):
v = self.article.title + "---" + self.tag.title
return v
class ArticleUpDown(models.Model):
"""
文章點贊表
哪個用戶對哪個文章點贊或點滅
"""
nid = models.AutoField(primary_key=True)
user = models.ForeignKey('UserInfo', null=True, on_delete=models.CASCADE)
article = models.ForeignKey("Article", null=True, on_delete=models.CASCADE)
is_up = models.BooleanField(default=True) # True:贊, False:滅
class Meta:
unique_together = [
('article', 'user'),
]
class Comment(models.Model):
"""
評論表
根評論:對文章的評論
子評論:對評論的評論
哪一個用戶對哪一篇文章在什么時間做了什么評論內容
nid user_id article_id content parent_comment_id(null=True)
1 1 1 111 null
2 2 1 222 null
3 3 1 333 null
4 4 1 444 1
5 5 1 555 4
"""
nid = models.AutoField(primary_key=True)
article = models.ForeignKey(verbose_name='評論文章', to='Article', to_field='nid', on_delete=models.CASCADE)
user = models.ForeignKey(verbose_name='評論者', to='UserInfo', to_field='nid', on_delete=models.CASCADE)
content = models.CharField(verbose_name='評論內容', max_length=255)
create_time = models.DateTimeField(verbose_name='創建時間', auto_now_add=True)
# parent_comment = models.ForeignKey("Comment") # 關聯Comment表,本身就在Comment表中,因此是自關聯
parent_comment = models.ForeignKey('self', null=True, on_delete=models.CASCADE) # 設置null=True,為null的情況不用存值了
def __str__(self):
return self.content
2、修改數據庫配置
settings.py:
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# }
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'cnblog', # 要連接的數據庫,連接前需要創建好
'USER': 'root', # 連接數據庫的用戶名
'PASSWORD': '1234', # 連接數據庫的密碼
'HOST': '127.0.0.1', # 連接主機,默認本機
'PORT': 3306 # 端口 默認3306
}
}
3、創建數據庫

4、數據庫遷移
(1)注意在遷移前檢查settings.py文件中,INSTALLED_APPS配置中是否自動加入了當前的APP:blog。
(2)另外由於在models.py中,用戶表繼承的是原生用戶表:AbstractUser,因此必須要在settings.py中做如下設置:
AUTH_USER_MODEL = 'blog.UserInfo'
執行數據庫遷移操作:
$ python3 manage.py makemigrations
(3)執行報錯:no module named MySQLdb 。這是因為django默認你導入的驅動是MySQLdb,可是MySQLdb 對於py3有很大問題,所以我們需要的驅動是PyMySQL ,所以要在/cnblog/cnblog/__init__.py里面寫入:
import pymysql pymysql.install_as_MySQLdb()
(4)執行數據庫遷移操作,完成數據庫遷移
$ python3 manage.py makemigrations $ python3 manage.py migrate
(5)在pycharm中配置數據庫

(6)查看數據庫中創建的表

可以看到auth_user表已經沒有了,user_info表中包含原生的字段和擴展的字段。user_info表既是用戶認證組件的user表也是自己的用戶表。
三、按着每一個功能進行開發
1、創建和配置靜態文件目錄
在項目根目錄下創建static 的python package。並在static下創建子目錄blog用於存放博客系統靜態文件。
在settings.py中配置靜態文件目錄:
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL = '/static/' # 別名
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static") # 實際路徑
]
配置好后,別名'/static/'就指代的是.../cnblog/static/目錄了。
拷入bootstrap文件:

四、功能測試
五、項目部署上線
