sync from local backup

This commit is contained in:
chunyu
2026-08-05 23:59:15 +08:00
commit d48ec1747c
358 changed files with 34384 additions and 0 deletions
View File
+23
View File
@@ -0,0 +1,23 @@
from django.contrib import admin
from django.utils.translation import gettext_lazy as _
from .models import Changelog
@admin.register(Changelog)
class ChangelogAdmin(admin.ModelAdmin):
list_display = ['version', 'title', 'update_type', 'published_at', 'is_published', 'created_at']
list_filter = ['update_type', 'is_published', 'published_at']
search_fields = ['version', 'title', 'description']
ordering = ['-published_at']
list_editable = ['is_published']
list_per_page = 20
date_hierarchy = 'published_at'
fieldsets = (
(_('Basic Information'), {
'fields': ('version', 'title', 'description')
}),
(_('Type and Publishing'), {
'fields': ('update_type', 'published_at', 'is_published')
}),
)
+5
View File
@@ -0,0 +1,5 @@
from django.apps import AppConfig
class AppConfig(AppConfig):
name = 'app'
View File
View File
@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
"""
创建初始更新日志测试数据的脚本
使用方法: python manage.py shell < app/management/commands/seed_changelogs.py
或: python manage.py shell -c "exec(open('app/management/commands/seed_changelogs.py').read())"
"""
from django.utils import timezone
from datetime import timedelta
from app.models import Changelog
# 删除现有数据
Changelog.objects.all().delete()
# 创建3条测试数据
changelogs = [
{
'version': 'v1.2.0',
'title': '新增AI智能助手功能',
'description': '''本次更新为大家带来了全新的AI智能助手功能!
主要更新内容:
1. 集成GPT-4智能问答助手,随时解答你的问题
2. 支持文章内容智能总结,一键生成摘要
3. 新增代码片段解释功能,编程更轻松
4. 优化响应速度,提升用户体验
我们一直在努力改进,希望能为用户提供更好的服务。''',
'update_type': 'new_feature',
'published_at': timezone.now(),
'is_published': True,
},
{
'version': 'v1.1.5',
'title': '性能优化与界面改进',
'description': '''本次更新主要针对性能优化和界面细节改进。
更新内容:
1. 优化页面加载速度,整体提升30%
2. 改进搜索算法,搜索结果更准确
3. 优化移动端适配,界面更美观
4. 修复若虹用户反馈的若干小问题
感谢大家的持续支持!''',
'update_type': 'improvement',
'published_at': timezone.now() - timedelta(days=7),
'is_published': True,
},
{
'version': 'v1.1.4',
'title': '修复已知问题',
'description': '''本次更新修复了以下问题:
1. 修复了用户在登录时偶发的验证码不显示问题
2. 修复了文章收藏后刷新页面数据丢失的问题
3. 修复了移动端导航栏显示异常的问题
4. 修复了部分浏览器下文件上传失败的问题
如遇到其他问题,请通过反馈入口告诉我们。''',
'update_type': 'bug_fix',
'published_at': timezone.now() - timedelta(days=14),
'is_published': True,
},
]
for data in changelogs:
Changelog.objects.create(**data)
print(f'成功创建 {len(changelogs)} 条更新日志测试数据')
for cl in Changelog.objects.all().order_by('-published_at'):
print(f" - {cl.version}: {cl.title} ({cl.get_update_type_display()})")
+41
View File
@@ -0,0 +1,41 @@
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Changelog',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('version', models.CharField(max_length=20, verbose_name='版本号')),
('title', models.CharField(max_length=200, verbose_name='更新标题')),
('description', models.TextField(verbose_name='详细描述')),
('update_type', models.CharField(
choices=[
('new_feature', '新功能'),
('improvement', '功能优化'),
('bug_fix', '问题修复'),
('other', '其他'),
],
default='other',
max_length=20,
verbose_name='更新类型'
)),
('published_at', models.DateTimeField(verbose_name='发布时间')),
('is_published', models.BooleanField(default=True, verbose_name='是否发布')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '更新日志',
'verbose_name_plural': '更新日志',
'ordering': ['-published_at'],
},
),
]
View File
+34
View File
@@ -0,0 +1,34 @@
from django.db import models
class Changelog(models.Model):
"""更新日志模型"""
UPDATE_TYPE_CHOICES = [
('new_feature', '新功能'),
('improvement', '功能优化'),
('bug_fix', '问题修复'),
('other', '其他'),
]
version = models.CharField(max_length=20, verbose_name='版本号')
title = models.CharField(max_length=200, verbose_name='更新标题')
description = models.TextField(verbose_name='详细描述')
update_type = models.CharField(
max_length=20,
choices=UPDATE_TYPE_CHOICES,
default='other',
verbose_name='更新类型'
)
published_at = models.DateTimeField(verbose_name='发布时间')
is_published = models.BooleanField(default=True, verbose_name='是否发布')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
verbose_name = '更新日志'
verbose_name_plural = '更新日志'
ordering = ['-published_at']
def __str__(self):
return f'{self.version} - {self.title}'
+21
View File
@@ -0,0 +1,21 @@
from rest_framework import serializers
from .models import Changelog
class ChangelogSerializer(serializers.ModelSerializer):
"""更新日志序列化器"""
update_type_display = serializers.CharField(
source='get_update_type_display',
read_only=True
)
class Meta:
model = Changelog
fields = [
'id', 'version', 'title', 'description',
'update_type', 'update_type_display',
'published_at', 'is_published',
'created_at', 'updated_at',
]
read_only_fields = ['created_at', 'updated_at']
+11
View File
@@ -0,0 +1,11 @@
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ChangelogViewSet
router = DefaultRouter()
router.register(r'changelogs', ChangelogViewSet, basename='changelog')
urlpatterns = [
path('', include(router.urls)),
]
+69
View File
@@ -0,0 +1,69 @@
from rest_framework import viewsets, permissions
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from chunyu_project.common_schemas import success_response
from .models import Changelog
from .serializers import ChangelogSerializer
class ChangelogPagination(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 100
def get_paginated_response(self, data):
return Response({
'code': 10000,
'message': 'Success',
'data': {
'count': self.page.paginator.count,
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'results': data,
}
})
class ChangelogViewSet(viewsets.ModelViewSet):
"""更新日志 ViewSet"""
queryset = Changelog.objects.filter(is_published=True)
serializer_class = ChangelogSerializer
permission_classes = [permissions.AllowAny]
pagination_class = ChangelogPagination
http_method_names = ['get']
def get_queryset(self):
queryset = Changelog.objects.filter(is_published=True)
update_type = self.request.query_params.get('update_type')
if update_type:
queryset = queryset.filter(update_type=update_type)
return queryset.order_by('-published_at')
@swagger_auto_schema(
tags=['更新日志'],
operation_summary='获取更新日志列表',
operation_description='获取已发布的更新日志列表,支持分页和按类型筛选',
manual_parameters=[
openapi.Parameter('update_type', openapi.IN_QUERY, description='更新类型筛选: new_feature/improvement/bug_fix/other', type=openapi.TYPE_STRING),
openapi.Parameter('page', openapi.IN_QUERY, description='页码', type=openapi.TYPE_INTEGER),
openapi.Parameter('page_size', openapi.IN_QUERY, description='每页数量', type=openapi.TYPE_INTEGER),
],
responses={200: success_response}
)
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)
@swagger_auto_schema(
tags=['更新日志'],
operation_summary='获取更新日志详情',
operation_description='获取指定更新日志的详细信息',
manual_parameters=[
openapi.Parameter('pk', openapi.IN_PATH, description='更新日志ID', type=openapi.TYPE_INTEGER, required=True),
],
responses={200: success_response}
)
def retrieve(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)