sync from local backup
This commit is contained in:
@@ -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')
|
||||
}),
|
||||
)
|
||||
@@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class AppConfig(AppConfig):
|
||||
name = 'app'
|
||||
@@ -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()})")
|
||||
@@ -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'],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -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}'
|
||||
@@ -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
@@ -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)),
|
||||
]
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user