目錄
1. 環境搭建與項目初始化
后端 (Django)
2. 數據庫模型設計
用戶認證模型 (Django Auth)
文章模型 (models.py)
全文索引優化
3. 后端API開發 (Django REST Framework)
用戶注冊/登錄
文章發布與搜索
4. 前端實現 (Vue 3)
項目初始化
核心功能實現
5. 訪問統計實現
后端中間件記錄PV/UV
6. 部署與優化
關鍵問題解決
1. 環境搭建與項目初始化
后端 (Django)
-
創建Django項目
django-admin startproject blog_backend cd blog_backend python manage.py startapp blog
-
安裝依賴
pip install django djangorestframework django-cors-headers djangorestframework-simplejwt mysqlclient
-
配置MySQL數據庫
修改?settings.py
:DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'blog_db','USER': 'root','PASSWORD': 'your_password','HOST': 'localhost','PORT': '3306',} }
-
配置DRF和JWT
修改?settings.py
:
INSTALLED_APPS = [# ...'rest_framework','corsheaders','blog',
]MIDDLEWARE = ['corsheaders.middleware.CorsMiddleware',# ...
]CORS_ALLOW_ALL_ORIGINS = True # 開發階段允許所有跨域REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_simplejwt.authentication.JWTAuthentication',)
}
2. 數據庫模型設計
用戶認證模型 (Django Auth)
直接使用Django內置的?User
?模型,無需額外設計。
文章模型 (models.py
)
from django.db import models
from django.contrib.auth.models import Userclass Article(models.Model):title = models.CharField(max_length=200)content = models.TextField() # 存儲Markdown或HTML內容author = models.ForeignKey(User, on_delete=models.CASCADE)category = models.CharField(max_length=50)tags = models.CharField(max_length=100) # 逗號分隔的標簽,如 "Python,Web"created_at = models.DateTimeField(auto_now_add=True)updated_at = models.DateTimeField(auto_now=True)def __str__(self):return self.titleclass Comment(models.Model):article = models.ForeignKey(Article, on_delete=models.CASCADE)user = models.ForeignKey(User, on_delete=models.CASCADE)content = models.TextField()parent_comment = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True) # 樹形評論created_at = models.DateTimeField(auto_now_add=True)
全文索引優化
在MySQL中為?Article
?表添加全文索引:
ALTER TABLE blog_article ADD FULLTEXT(title, content);
3. 后端API開發 (Django REST Framework)
用戶注冊/登錄
-
序列化器 (
serializers.py
)from rest_framework import serializers from django.contrib.auth.models import Userclass UserSerializer(serializers.ModelSerializer):class Meta:model = Userfields = ('id', 'username', 'email', 'password')extra_kwargs = {'password': {'write_only': True}}def create(self, validated_data):user = User.objects.create_user(**validated_data)return user
-
視圖 (
views.py
)from rest_framework.views import APIView from rest_framework.response import Response from rest_framework_simplejwt.tokens import RefreshTokenclass RegisterView(APIView):def post(self, request):serializer = UserSerializer(data=request.data)if serializer.is_valid():user = serializer.save()refresh = RefreshToken.for_user(user)return Response({'refresh': str(refresh),'access': str(refresh.access_token),})return Response(serializer.errors, status=400)
文章發布與搜索
-
文章序列化器
class ArticleSerializer(serializers.ModelSerializer):class Meta:model = Articlefields = '__all__'
-
文章搜索接口
使用Django ORM的全文搜索:class ArticleSearchView(APIView):def get(self, request):query = request.query_params.get('q', '')# MySQL全文搜索語法articles = Article.objects.raw("SELECT * FROM blog_article WHERE MATCH(title, content) AGAINST (%s)",[query])serializer = ArticleSerializer(articles, many=True)return Response(serializer.data)
4. 前端實現 (Vue 3)
項目初始化
npm create vue@latest blog_frontend
cd blog_frontend
npm install axios vue-router vuex quill @vueuse/core
核心功能實現
-
Markdown渲染
使用?marked
?或?vue-markdown
?庫:<template><div v-html="compiledMarkdown"></div> </template><script setup> import { marked } from 'marked' const compiledMarkdown = marked(props.content) </script>
-
富文本編輯器集成 (Quill)
<template><div ref="editor"></div> </template><script setup> import Quill from 'quill' import 'quill/dist/quill.snow.css'const editor = ref(null) onMounted(() => {const quill = new Quill(editor.value, {theme: 'snow',modules: { toolbar: true }}) }) </script>
-
動態路由SEO優化
使用?vue-router
?和預渲染插件?prerender-spa-plugin
:// vue.config.js const PrerenderSPAPlugin = require('prerender-spa-plugin')module.exports = {configureWebpack: {plugins: [new PrerenderSPAPlugin({staticDir: path.join(__dirname, 'dist'),routes: ['/', '/articles', '/about'], // 預渲染的路由})]} }
5. 訪問統計實現
后端中間件記錄PV/UV
-
創建訪問記錄模型
class AccessLog(models.Model):ip = models.CharField(max_length=50)path = models.CharField(max_length=200)user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)created_at = models.DateTimeField(auto_now_add=True)
-
中間件統計訪問量
class AccessLogMiddleware:def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):response = self.get_response(request)AccessLog.objects.create(ip=request.META.get('REMOTE_ADDR'),path=request.path,user=request.user if request.user.is_authenticated else None)return response
6. 部署與優化
-
MySQL全文索引查詢優化
確保MySQL版本 >= 5.6,并配置索引:CREATE FULLTEXT INDEX ft_idx ON blog_article(title, content);
-
Nginx配置反向代理
server {listen 80;server_name your_domain.com;location /api {proxy_pass http://localhost:8000;proxy_set_header Host $host;}location / {root /path/to/vue/dist;try_files $uri $uri/ /index.html;} }
-
性能優化
-
使用?
django-debug-toolbar
?分析查詢 -
Vue路由懶加載:
const routes = [{ path: '/article/:id', component: () => import('./views/ArticleDetail.vue') } ]
-
關鍵問題解決
-
跨域配置
使用?django-cors-headers
,確保前端能訪問后端API。 -
樹形評論渲染
前端遞歸組件實現:<template><div v-for="comment in comments" :key="comment.id"><div>{{ comment.content }}</div><CommentTree v-if="comment.replies" :comments="comment.replies"/></div> </template>
-
JWT Token自動刷新
使用Axios攔截器:axios.interceptors.response.use(response => response, error => {if (error.response.status === 401) {return refreshToken().then(() => {return axios(error.config)})}return Promise.reject(error) })
通過以上步驟,你可以逐步搭建一個功能完整的博客系統。建議先從基礎功能(如文章發布)開始,逐步迭代添加評論、搜索等模塊。