10305 - Ordering Tasks(****)拓扑排序

本文介绍如何使用深度优先搜索算法解决拓扑排序问题,通过实例代码演示了从输入到输出的完整过程。
/* 简单拓扑排序问题 深度优先,数组st作为存储 */ #include <cstdio> #include <cstring> const int nMax=105; int n,m; int G[nMax][nMax],visit[nMax],st[nMax]; int top; void dfs(int u) { visit[u]=1; for(int v=1;v<=n;v++) { if(G[u][v] && !visit[v]) dfs(v); } st[--top]=u; } int main() { //freopen("data.in","r",stdin); while(scanf("%d %d",&n,&m)==2) { if(n==0 && m==0) break; memset(G,0,sizeof(G)); memset(visit,0,sizeof(visit)); for(int i=0;i<m;i++) { int a,b; scanf("%d %d",&a,&b); G[a][b]=1; } top=n; for(int i=1;i<=n;i++) { if(!visit[i]) dfs(i); } for(int i=0;i<n;i++) { printf("%d ",st[i]); } printf("\n"); } return 0; }

我需要开发一个基于 Python 3.13.7+Django 5.2.6+MySQL 8.4 的前后端分离博客项目,需要完整的代码流程,要求如下: ## 1. 项目概述 - 开发一个功能完整、界面美观、交互友好的现代化博客系统 - 采用前后端完全分离的架构,Django 作为后端 API 服务,前端采用主流框架独立开发 - 注重用户体验和视觉设计,确保界面美观、有设计感 - 实现高性能、高可用、可扩展的系统架构 ## 2. 技术栈要求 - **后端**:Python 3.13.7,Django 5.2.6,Django REST Framework - **数据库**:MySQL 8.4,优化表结构和索引设计 - **认证**:JWT (JSON Web Tokens) 认证机制 - **前端**:React 18+,TypeScript,Ant Design 5. X,Redux Toolkit - **构建工具**:Poetry (Python 依赖管理),Vite (前端构建) - **API 文档**:Swagger/OpenAPI 自动生成文档 ## 3. 视觉设计用户体验 - **UI 设计**:要求现代化、简约而不简单,具有良好的视觉层次感 - **色彩方案**:设计专业的配色方案,主色调选择稳重而不失活力的蓝色系或深灰色系 - **排版**:精心设计的排版系统,确保文章阅读体验舒适 - **动画效果**:添加适当的过渡动画和交互反馈,但不过度使用 - **响应式设计**:完全适配移动端、平板和桌面端 - **可访问性**:符合 WCAG 标准,支持键盘导航和屏幕阅读器 ## 4. 核心功能模块 ### 4.1 用户管理模块 - 用户注册、登录、注销功能 - 个人信息管理(头像、简介、密码等) - 角色权限控制(普通用户、作者、管理员) - 邮箱验证和密码重置功能 - 用户贡献热力图展示(类似 GitHub 贡献图) ### 4.2 博客文章模块 - 文章的 CRUD 操作,支持草稿保存 - 富文本编辑功能,支持图片、视频插入 - 文章分类和标签管理 - 文章评论系统,支持多级回复 - 文章阅读量统计和热门文章推荐 - 文章分享功能 - 文章收藏功能 ### 4.3 媒体管理模块 - 图片、视频等媒体文件的上传、管理 - 媒体文件分类和搜索 - 媒体文件预览功能 - 支持拖拽上传和批量上传 - 图片压缩和格式转换 ### 4.4 评论互动模块 - 多级评论系统,支持回复功能 - 评论点赞和踩功能 - 评论排序和筛选 - 评论通知功能 - 敏感词过滤和评论审核 ### 4.5 搜索模块 - 全文搜索功能,支持模糊匹配 - 高级筛选功能(按分类、标签、日期等) - 搜索结果排序和分页 - 搜索建议和历史记录 ### 4.6 统计分析模块 - 文章访问量统计和分析 - 用户活跃度统计 - 热门内容排行 - 系统使用情况监控 - 基于 grid 网格布局的贡献热力图,使用 54 列(周数)和 7 行(星期几)来展示用户活跃度,当用户将鼠标悬停在热力图的某个格子上时,提示框将显示日期周几和贡献次数,让用户能够更清楚地了解每一天的具体情况。 ### 4.7 系统管理模块 - 用户管理和权限分配 - 内容审核和管理 - 系统配置和参数设置 - 数据备份和恢复 ## 5. 技术架构性能优化 - **模块化设计**:按功能模块划分 Django 应用 - **数据库优化**:合理设计表结构、索引,优化查询性能 - **API 性能优化**:实现缓存策略,减少数据库查询 - **前端性能优化**:代码分割、懒加载、资源优化 - **安全性设计**:CSRF 防护、XSS 过滤、SQL 注入防护、敏感数据加密 - **跨域处理**:配置 CORS 策略 - **错误处理**:统一的异常处理机制 - **日志系统**:完善的日志记录和分析系统 ## 6. 开发测试环境 - **环境配置**:区分开发、测试、生产环境配置 - **版本控制**:使用 Git 进行代码管理 - **代码规范**:遵循 PEP 8 和业内最佳实践 - **测试策略**:单元测试、集成测试、端到端测试 - **CI/CD**:配置持续集成和持续部署流程 - **开发工具**:推荐使用 VSCode、PyCharm 等 IDE ## 7. 项目交付要求 - **项目文档**:详细的技术文档、API 文档和使用说明 - **源代码**:完整的前后端源代码,组织良好的项目结构 - **示例数据**:提供测试用的示例数据 - **部署指南**:详细的部署步骤和环境配置说明 - **性能报告**:系统性能测试报告 ## 8. 扩展功能 - **社交分享**:集成主流社交平台分享功能 - **SEO 优化**:针对搜索引擎的优化 - **Markdown 编辑器**:支持 Markdown 格式文章编辑 - **定时发布**:文章定时发布功能 - **主题切换**:支持深色/浅色主题切换 - **多语言支持**:国际化和本地化支持 - **RSS 订阅**:提供内容订阅功能 - **通知系统**:站内信和邮件通知 请基于以上需求,提供完整的项目开发方案以及所有相关代码文件,包括但不限于: - 源代码:提供完整的前后端源代码,组织良好的项目目录结构 - 数据库设计 - API 设计 - 前后端实现思路 - 部署方案 - 关键技术点和解决方案 - 完整详细的开发流程,确保本地成功运行
最新发布
09-29
<think>我们正在构建一个完整的前后端分离的博客系统。由于项目规模较大,我将分步骤提供关键部分的代码和解释。 首先,我们需要创建Django后端项目,然后创建React前端项目。 步骤: 1. 创建Django项目并设置虚拟环境(使用Poetry) 2. 配置Django使用MySQL数据库 3. 创建Django应用(用户管理、博客、评论、搜索等) 4. 使用Django REST Framework构建API 5. 配置JWT认证 6. 配置Swagger生成API文档 7. 创建React前端项目,使用Vite、TypeScript、Ant Design和Redux Toolkit 8. 实现前端路由、页面和组件 9. 前后端联调 10. 部署方案 由于篇幅限制,我将提供关键部分的代码示例和架构设计。 一、后端项目设置 1. 使用Poetry初始化项目 ```bash poetry new blog_backend cd blog_backend poetry add django djangorestframework django-cors-headers mysqlclient drf_yasg djangorestframework-simplejwt pillow ``` 2. 创建Django项目 ```bash poetry run django-admin startproject blog . ``` 3. 创建应用 ```bash poetry run python manage.py startapp users poetry run python manage.py startapp blog poetry run python manage.py startapp comments poetry run python manage.py startapp media poetry run python manage.py startapp search ``` 4. 配置数据库(MySQL) 在settings.py中配置: ```python DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'blogdb', 'USER': 'root', 'PASSWORD': 'yourpassword', 'HOST': 'localhost', 'PORT': '3306', 'OPTIONS': { 'charset': 'utf8mb4', } } } ``` 5. 配置Django REST Framework和JWT 在settings.py中添加: ```python INSTALLED_APPS = [ ... 'rest_framework', 'corsheaders', 'drf_yasg', 'users', 'blog', ... ] MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware', ... ] # 跨域设置 CORS_ORIGIN_ALLOW_ALL = True # 开发阶段可以允许所有,生产环境应设置具体域名 # DRF配置 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', ), } # JWT设置 from datetime import timedelta SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60), 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), } ``` 6. 用户模型设计(users/models.py) 扩展Django的AbstractUser: ```python from django.db import models from django.contrib.auth.models import AbstractUser class User(AbstractUser): bio = models.TextField(max_length=500, blank=True) avatar = models.ImageField(upload_to='avatars/', blank=True, null=True) role = models.CharField(max_length=20, choices=[ ('user', '普通用户'), ('author', '作者'), ('admin', '管理员'), ], default='user') class Meta: verbose_name = '用户' verbose_name_plural = verbose_name def __str__(self): return self.username ``` 然后在settings.py中设置AUTH_USER_MODEL: ```python AUTH_USER_MODEL = 'users.User' ``` 7. 用户注册和登录API(users/views.py) 使用DRF的APIView: ```python from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from .serializers import UserRegisterSerializer, UserLoginSerializer from django.contrib.auth import authenticate from rest_framework_simplejwt.tokens import RefreshToken class UserRegisterView(APIView): def post(self, request): serializer = UserRegisterSerializer(data=request.data) if serializer.is_valid(): user = serializer.save() # 创建JWT token refresh = RefreshToken.for_user(user) return Response({ 'refresh': str(refresh), 'access': str(refresh.access_token), }, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class UserLoginView(APIView): def post(self, request): serializer = UserLoginSerializer(data=request.data) if serializer.is_valid(): username = serializer.validated_data['username'] password = serializer.validated_data['password'] user = authenticate(username=username, password=password) if user: refresh = RefreshToken.for_user(user) return Response({ 'refresh': str(refresh), 'access': str(refresh.access_token), }) else: return Response({'error': 'Invalid Credentials'}, status=status.HTTP_401_UNAUTHORIZED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) ``` 8. 序列化器(users/serializers.py) ```python from rest_framework import serializers from .models import User class UserRegisterSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True) class Meta: model = User fields = ['username', 'email', 'password', 'bio', 'avatar'] def create(self, validated_data): user = User.objects.create_user( username=validated_data['username'], email=validated_data['email'], password=validated_data['password'], bio=validated_data.get('bio', ''), avatar=validated_data.get('avatar', None) ) return user class UserLoginSerializer(serializers.Serializer): username = serializers.CharField() password = serializers.CharField() ``` 9. 配置URL(users/urls.py) ```python from django.urls import path from .views import UserRegisterView, UserLoginView urlpatterns = [ path('register/', UserRegisterView.as_view(), name='register'), path('login/', UserLoginView.as_view(), name='login'), ] ``` 10. 在项目总路由中引入(blog/urls.py) ```python from django.urls import path, include urlpatterns = [ ... path('api/users/', include('users.urls')), ... ] ``` 以上是用户注册和登录的API实现。接下来,我们设计博客文章模型。 二、博客文章模块(blog应用) 1. 模型设计(blog/models.py) ```python from django.db import models from django.contrib.auth import get_user_model from django.urls import reverse from django.utils.text import slugify User = get_user_model() class Category(models.Model): name = models.CharField(max_length=50) def __str__(self): return self.name class Tag(models.Model): name = models.CharField(max_length=50) def __str__(self): return self.name class Post(models.Model): title = models.CharField(max_length=200) slug = models.SlugField(max_length=200, unique=True, blank=True) content = models.TextField() created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) author = models.ForeignKey(User, on_delete=models.CASCADE) category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True) tags = models.ManyToManyField(Tag) is_published = models.BooleanField(default=False) published_date = models.DateTimeField(null=True, blank=True) views = models.PositiveIntegerField(default=0) def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.title) super().save(*args, **kwargs) def get_absolute_url(self): return reverse('post-detail', args=[str(self.slug)]) def __str__(self): return self.title class Comment(models.Model): post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments') author = models.ForeignKey(User, on_delete=models.CASCADE) content = models.TextField() created_at = models.DateTimeField(auto_now_add=True) parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='replies') likes = models.PositiveIntegerField(default=0) dislikes = models.PositiveIntegerField(default=0) class Meta: ordering = ['created_at'] def __str__(self): return f'Comment by {self.author} on {self.post}' ``` 注意:这里将评论设计为自关联,以实现多级评论。 2. 序列化器(blog/serializers.py) ```python from rest_framework import serializers from .models import Post, Category, Tag, Comment class CategorySerializer(serializers.ModelSerializer): class Meta: model = Category fields = ['id', 'name'] class TagSerializer(serializers.ModelSerializer): class Meta: model = Tag fields = ['id', 'name'] class CommentSerializer(serializers.ModelSerializer): author = serializers.ReadOnlyField(source='author.username') replies = serializers.SerializerMethodField() class Meta: model = Comment fields = ['id', 'author', 'content', 'created_at', 'parent', 'replies', 'likes', 'dislikes'] def get_replies(self, obj): if obj.replies.exists(): return CommentSerializer(obj.replies.all(), many=True).data return [] class PostSerializer(serializers.ModelSerializer): author = serializers.ReadOnlyField(source='author.username') category = CategorySerializer(read_only=True) tags = TagSerializer(many=True, read_only=True) class Meta: model = Post fields = ['id', 'title', 'slug', 'content', 'created_at', 'updated_at', 'author', 'category', 'tags', 'is_published', 'published_date', 'views'] ``` 3. 视图(blog/views.py) 使用DRF的视图集(ViewSet)和ModelViewSet: ```python from rest_framework import viewsets from .models import Post, Comment from .serializers import PostSerializer, CommentSerializer from rest_framework.permissions import IsAuthenticatedOrReadOnly, IsAuthenticated from .permissions import IsOwnerOrReadOnly class PostViewSet(viewsets.ModelViewSet): queryset = Post.objects.all() serializer_class = PostSerializer permission_classes = [IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly] def perform_create(self, serializer): serializer.save(author=self.request.user) class CommentViewSet(viewsets.ModelViewSet): queryset = Comment.objects.all() serializer_class = CommentSerializer permission_classes = [IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly] def perform_create(self, serializer): serializer.save(author=self.request.user) ``` 4. 权限(blog/permissions.py) ```python from rest_framework import permissions class IsOwnerOrReadOnly(permissions.BasePermission): def has_object_permission(self, request, view, obj): if request.method in permissions.SAFE_METHODS: return True return obj.author == request.user ``` 5. 路由(blog/urls.py) ```python from django.urls import path, include from rest_framework.routers import DefaultRouter from . import views router = DefaultRouter() router.register(r'posts', views.PostViewSet) router.register(r'comments', views.CommentViewSet) urlpatterns = [ path('', include(router.urls)), ] ``` 然后在项目总路由中包含它。 三、数据库迁移 执行迁移命令: ```bash poetry run python manage.py makemigrations poetry run python manage.py migrate ``` 四、配置媒体文件 在settings.py中: ```python MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') ``` 在urls.py中添加: ```python from django.conf import settings from django.conf.urls.static import static if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ``` 五、配置Swagger 在项目总urls.py中添加: ```python from django.urls import path from rest_framework import permissions from drf_yasg.views import get_schema_view from drf_yasg import openapi schema_view = get_schema_view( openapi.Info( title="Blog API", default_version='v1', description="API documentation for the Blog project", ), public=True, permission_classes=[permissions.AllowAny], ) urlpatterns = [ ... path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), ... ] ``` 六、前端项目创建(使用Vite和React) 1. 创建项目 ```bash npm create vite@latest blog_frontend -- --template react-ts cd blog_frontend npm install npm install antd @ant-design/icons axios react-router-dom@6 @reduxjs/toolkit react-redux ``` 2. 设置代理(vite.config.ts) 在vite.config.ts中添加代理,解决跨域问题: ```javascript import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], server: { proxy: { '/api': { target: 'http://localhost:8000', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') } } } }) ``` 3. 配置Redux Toolkit 创建store.ts: ```typescript import { configureStore } from '@reduxjs/toolkit' import authReducer from './features/authSlice' export const store = configureStore({ reducer: { auth: authReducer } }) export type RootState = ReturnType<typeof store.getState> export type AppDispatch = typeof store.dispatch ``` 创建authSlice.ts: ```typescript import { createSlice, PayloadAction } from '@reduxjs/toolkit' interface AuthState { user: string | null token: string | null } const initialState: AuthState = { user: null, token: null } const authSlice = createSlice({ name: 'auth', initialState, reducers: { setCredentials: (state, action: PayloadAction<{ user: string, token: string }>) => { state.user = action.payload.user state.token = action.payload.token }, logout: (state) => { state.user = null state.token = null } } }) export const { setCredentials, logout } = authSlice.actions export default authSlice.reducer ``` 4. 创建登录页面(Login.tsx) 使用Ant Design组件: ```tsx import { LockOutlined, UserOutlined } from '@ant-design/icons' import { Button, Checkbox, Form, Input } from 'antd' import React from 'react' import { useDispatch } from 'react-redux' import { setCredentials } from './features/authSlice' import axios from 'axios' const Login: React.FC = () => { const dispatch = useDispatch() const onFinish = async (values: any) => { try { const response = await axios.post('/api/users/login/', { username: values.username, password: values.password }) const { access: token } = response.data dispatch(setCredentials({ user: values.username, token })) // 保存token到localStorage localStorage.setItem('token', token) } catch (error) { console.error('Login failed:', error) } } return ( <Form name="normal_login" initialValues={{ remember: true }} onFinish={onFinish} > <Form.Item name="username" rules={[{ required: true, message: 'Please input your Username!' }]} > <Input prefix={<UserOutlined />} placeholder="Username" /> </Form.Item> <Form.Item name="password" rules={[{ required: true, message: 'Please input your Password!' }]} > <Input prefix={<LockOutlined />} type="password" placeholder="Password" /> </Form.Item> <Form.Item> <Button type="primary" htmlType="submit" block> Log in </Button> </Form.Item> </Form> ) } export default Login ``` 由于项目功能模块众多,无法在此一一展示所有代码。以上提供了关键部分的代码示例。 七、部署方案 1. 后端部署:可以使用Gunicorn + Nginx部署Django项目 2. 前端部署:使用Vite构建,将生成的dist目录部署到Nginx服务器 八、数据库设计(MySQL) 根据前面的模型设计,生成数据库表。建议使用InnoDB引擎,并为常用查询字段添加索引,如文章的标题、创建时间,用户的用户名等。 九、关键技术点和解决方案 - 前后端分离:使用Django REST Framework提供API,前端使用React独立开发 - JWT认证:使用simplejwt库实现,前端在请求头中添加Authorization: Bearer <token> - 评论树:通过自关联模型实现多级评论,序列化时递归生成嵌套结构 - 热力图:使用ECharts或D3.js实现,前后端配合统计数据 十、完整开发流程 1. 克隆项目 2. 后端:使用Poetry安装依赖,配置MySQL,执行迁移,运行开发服务器 3. 前端:npm安装依赖,运行开发服务器 4. 访问前端地址(如http://localhost:5173)进行开发 由于项目需求详细且复杂,以上是一个基础框架。在实际开发中,需要根据需求逐步完善各模块功能。 §§相关问题§§: 1. 如何实现用户贡献热力图? 2. 如何在前端实现多级评论的展示? 3. 如何优化Django的查询性能? 4. 如何进行前后端的API联调? </think>以下是为您设计的完整前后端分离博客项目解决方案。由于项目规模较大,我将分模块展示核心代码和实现思路: ### 1. 项目结构 ``` blog-project/ ├── backend/ # Django 后端 │ ├── blog/ # 主应用 │ ├── users/ # 用户管理 │ ├── media/ # 媒体管理 │ ├── search/ # 搜索模块 │ ├── core/ # 核心配置 │ └── manage.py ├── frontend/ # React 前端 │ ├── src/ │ │ ├── features/ # 功能模块 │ │ ├── components/ # 通用组件 │ │ ├── api/ # API 服务 │ │ └── App.tsx │ └── vite.config.ts └── docker-compose.yml # 容器化部署 ``` ### 2. 数据库设计 (MySQL) ```sql -- 用户表 CREATE TABLE `users` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `username` VARCHAR(150) UNIQUE NOT NULL, `email` VARCHAR(254) UNIQUE NOT NULL, `password` VARCHAR(128) NOT NULL, `avatar` VARCHAR(200) NULL, `role` ENUM('user', 'author', 'admin') DEFAULT 'user', `last_login` DATETIME NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 博客文章表 CREATE TABLE `posts` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `title` VARCHAR(200) NOT NULL, `slug` VARCHAR(200) UNIQUE NOT NULL, `content` LONGTEXT NOT NULL, `author_id` INT NOT NULL, `status` ENUM('draft', 'published') DEFAULT 'draft', `created_at` DATETIME NOT NULL, `updated_at` DATETIME NOT NULL, FOREIGN KEY (`author_id`) REFERENCES `users`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 评论表(支持多级回复) CREATE TABLE `comments` ( `id` BIGINT AUTO_INCREMENT PRIMARY KEY, `post_id` INT NOT NULL, `user_id` INT NOT NULL, `parent_id` BIGINT NULL, `content` TEXT NOT NULL, `created_at` DATETIME NOT NULL, FOREIGN KEY (`post_id`) REFERENCES `posts`(`id`), FOREIGN KEY (`user_id`) REFERENCES `users`(`id`), FOREIGN KEY (`parent_id`) REFERENCES `comments`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### 3. 后端核心实现 (Django) #### 用户认证模块 (users/views.py) ```python from rest_framework.views import APIView from rest_framework_simplejwt.tokens import RefreshToken from rest_framework import status from .serializers import UserRegisterSerializer class RegisterView(APIView): def post(self, request): serializer = UserRegisterSerializer(data=request.data) if serializer.is_valid(): user = serializer.save() # 生成JWT令牌 refresh = RefreshToken.for_user(user) return Response({ 'access': str(refresh.access_token), 'refresh': str(refresh) }, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class UserActivityView(APIView): authentication_classes = [JWTAuthentication] def get(self, request): # 实现用户贡献热力图数据 user = request.user activity = UserActivity.objects.filter(user=user).annotate( week=ExtractWeek('date'), weekday=ExtractWeekDay('date') ).values('week', 'weekday').annotate(count=Count('id')) return Response({ "activity_map": activity, "username": user.username }) ``` #### 博客文章API (blog/views.py) ```python class PostViewSet(viewsets.ModelViewSet): queryset = Post.objects.select_related('author').prefetch_related('tags') serializer_class = PostSerializer filterset_class = PostFilter permission_classes = [IsAuthenticatedOrReadOnly] def perform_create(self, serializer): serializer.save(author=self.request.user) @action(detail=True, methods=['POST']) def upload_image(self, request, pk=None): # 富文本编辑器图片上传 image = request.FILES.get('image') img = Image.open(image) img = img.convert('RGB') img.thumbnail((1200, 1200)) output = BytesIO() img.save(output, format='JPEG', quality=85) output.seek(0) image_file = InMemoryUploadedFile( output, 'ImageField', f"{uuid4()}.jpg", 'image/jpeg', sys.getsizeof(output), None ) media = Media.objects.create( file=image_file, user=request.user, media_type='image' ) return Response({ 'url': media.file.url }, status=HTTP_201_CREATED) ``` ### 4. 前端核心实现 (React + TypeScript) #### API服务层 (frontend/src/api/client.ts) ```typescript import axios, { AxiosRequestConfig } from 'axios'; const api = axios.create({ baseURL: import.meta.env.VITE_API_URL, }); // JWT 认证拦截器 api.interceptors.request.use(config => { const token = localStorage.getItem('access_token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); // 响应拦截器 api.interceptors.response.use( response => response, async error => { const originalRequest = error.config; if (error.response.status === 401 && !originalRequest._retry) { originalRequest._retry = true; const refreshToken = localStorage.getItem('refresh_token'); const { data } = await api.post('/auth/token/refresh/', { refresh: refreshToken }); localStorage.setItem('access_token', data.access); return api(originalRequest); } return Promise.reject(error); } ); export default api; ``` #### 用户热力图组件 (frontend/src/components/ActivityHeatmap.tsx) ```tsx import { Tooltip } from 'antd'; import { useEffect, useState } from 'react'; const ActivityHeatmap = () => { const [activities, setActivities] = useState<Record<string, number>>({}); useEffect(() => { api.get('/user/activity/').then(res => { const map: Record<string, number> = {}; res.data.activity_map.forEach((item: any) => { map[`${item.week}-${item.weekday}`] = item.count; }); setActivities(map); }); }, []); const renderGrid = () => { const grids = []; for (let week = 1; week <= 54; week++) { for (let day = 1; day <= 7; day++) { const key = `${week}-${day}`; const count = activities[key] || 0; // 根据活动次数计算颜色深浅 const colorIntensity = count > 0 ? Math.min(4, Math.floor(count / 3)) : 0; const color = `bg-green-${colorIntensity > 0 ? 300 + colorIntensity * 100 : 100}`; grids.push( <Tooltip key={key} title={`Week ${week}, Day ${day}: ${count} activities`} > <div className={`w-3 h-3 m-0.5 ${color} rounded-sm hover:border hover:border-gray-500`} /> </Tooltip> ); } } return grids; }; return ( <div className="flex flex-wrap max-w-4xl"> {renderGrid()} </div> ); }; ``` ### 5. 关键技术解决方案 #### JWT 认证流程 ```mermaid sequenceDiagram participant F as Frontend participant B as Backend F->>B: POST /auth/login/ (credentials) B-->>F: {access, refresh} tokens F->>B: API请求 (Authorization: Bearer <access>) alt Token过期 B-->>F: 401 Unauthorized F->>B: POST /auth/token/refresh/ (refresh token) B-->>F: 新的access token F->>B: 重试原始请求 end ``` #### 性能优化策略 1. **数据库层**: - 使用`select_related`和`prefetch_related`减少查询次数 - 添加复合索引(如用户活动表的(date, user_id)) 2. **API层**: - 使用Django Cache Framework缓存频繁访问数据 ```python from django.core.cache import cache def get_popular_posts(): key = 'popular_posts' posts = cache.get(key) if not posts: posts = Post.objects.filter(status='published') \ .annotate(like_count=Count('likes')) \ .order_by('-like_count')[:10] cache.set(key, posts, timeout=60*15) # 15分钟缓存 return posts ``` 3. **前端优化**: - 使用React.lazy进行路由懒加载 ```tsx const Editor = lazy(() => import('./components/RichTextEditor')); <Suspense fallback={<Spin />}> <Editor /> </Suspense> ``` ### 6. 部署方案 (Docker) ```yaml # docker-compose.yml version: '3.8' services: db: image: mysql:8.4 environment: MYSQL_DATABASE: blogdb MYSQL_USER: bloguser MYSQL_PASSWORD: securepass MYSQL_ROOT_PASSWORD: rootpass volumes: - mysql_data:/var/lib/mysql backend: build: ./backend command: gunicorn core.wsgi:application --bind 0.0.0.0:8000 volumes: - ./backend:/app - media_volume:/app/media ports: - "8000:8000" depends_on: - db frontend: build: context: ./frontend dockerfile: Dockerfile ports: - "5173:80" depends_on: - backend volumes: mysql_data: media_volume: ``` ### 7. 完整开发流程 1. **环境准备**: ```bash # 后端 poetry install python manage.py migrate python manage.py runserver # 前端 npm install npm run dev ``` 2. **测试数据生成**: ```python # 使用django-seed生成测试数据 from django_seed import Seed seeder = Seed.seeder() seeder.add_entity(User, 10) seeder.add_entity(Post, 50) seeder.execute() ``` 3. **API文档访问**: ``` http://localhost:8000/swagger/ ``` 4. **生产部署**: ```bash docker-compose up -d --build ``` ### 8. 关键技术点 1. **富文本编辑器**:使用Quill.js封装React组件 2. **深度评论系统**:使用MPTT算法实现多级评论 3. **实时搜索**:Elasticsearch集成实现模糊匹配 4. **主题切换**:CSS变量+React Context实现 ```tsx const ThemeContext = createContext<ThemeContextType>({ darkMode: false, toggleTheme: () => {} }); const ThemeProvider = ({children}: Props) => { const [darkMode, setDarkMode] = useState(false); useEffect(() => { // 应用CSS变量 document.documentElement.style.setProperty( '--bg-primary', darkMode ? '#1a1a1a' : '#ffffff' ); }, [darkMode]); return ( <ThemeContext.Provider value={{ darkMode, toggleTheme: () => setDarkMode(!darkMode) }}> {children} </ThemeContext.Provider> ); }; ``` 5. **贡献热力图**:D3.js + 后端聚合计算 6. **媒体处理**:使用Pillow进行图片压缩和格式转换
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值