feat: 移除轮播图管理,系列活动改卡片布局,课程描述限10行,首页配置优化
All checks were successful
Deploy to Server / deploy (push) Successful in 2m4s
All checks were successful
Deploy to Server / deploy (push) Successful in 2m4s
This commit is contained in:
@@ -2,28 +2,20 @@ from django.contrib import admin
|
||||
from django.utils.html import format_html
|
||||
from unfold.admin import ModelAdmin
|
||||
from unfold.decorators import display
|
||||
from .models import Competition, CompetitionEnrollment, ScoreDimension, Project, ProjectFile, Score, Comment, HomePageConfig, CarouselItem
|
||||
|
||||
|
||||
class CarouselItemInline(admin.TabularInline):
|
||||
model = CarouselItem
|
||||
extra = 1
|
||||
tab = True
|
||||
fields = ('carousel_type', 'image', 'image_url', 'title', 'subtitle', 'status', 'status_color', 'date', 'location', 'order', 'is_active')
|
||||
autocomplete_fields = []
|
||||
from .models import Competition, CompetitionEnrollment, ScoreDimension, Project, ProjectFile, Score, Comment, HomePageConfig
|
||||
|
||||
|
||||
@admin.register(HomePageConfig)
|
||||
class HomePageConfigAdmin(ModelAdmin):
|
||||
list_display = ['id', 'main_title', 'carousel1_title', 'carousel2_title', 'organizer', 'undertaker', 'is_active']
|
||||
list_editable = ['main_title', 'carousel1_title', 'carousel2_title', 'organizer', 'undertaker', 'is_active']
|
||||
list_display = ['id', 'main_title', 'organizer', 'undertaker', 'is_active']
|
||||
list_editable = ['main_title', 'organizer', 'undertaker', 'is_active']
|
||||
fieldsets = (
|
||||
('首页Banner', {
|
||||
('封面图', {
|
||||
'fields': ('banner_image', 'banner_image_url'),
|
||||
'description': '首页顶部Banner图片,可以上传本地图片或填写URL'
|
||||
'description': '首页标题下方的封面图,可上传本地图片或填写URL'
|
||||
}),
|
||||
('标题设置', {
|
||||
'fields': ('main_title', 'carousel1_title', 'carousel2_title')
|
||||
'fields': ('main_title',)
|
||||
}),
|
||||
('主办单位', {
|
||||
'fields': ('organizer', 'undertaker')
|
||||
@@ -34,37 +26,6 @@ class HomePageConfigAdmin(ModelAdmin):
|
||||
)
|
||||
|
||||
|
||||
@admin.register(CarouselItem)
|
||||
class CarouselItemAdmin(ModelAdmin):
|
||||
list_display = ['title', 'carousel_type', 'status', 'location', 'order', 'is_active', 'created_at']
|
||||
list_filter = ['carousel_type', 'status', 'is_active']
|
||||
search_fields = ['title', 'subtitle', 'location']
|
||||
readonly_fields = ['image_preview']
|
||||
fieldsets = (
|
||||
('轮播图类型', {
|
||||
'fields': ('carousel_type',)
|
||||
}),
|
||||
('图片设置', {
|
||||
'fields': ('image', 'image_preview', 'image_url'),
|
||||
'description': '优先使用本地上传的图片,上传后可预览'
|
||||
}),
|
||||
('内容设置', {
|
||||
'fields': ('title', 'subtitle', 'status', 'status_color', 'date', 'location')
|
||||
}),
|
||||
('显示设置', {
|
||||
'fields': ('order', 'is_active')
|
||||
}),
|
||||
)
|
||||
|
||||
@display(description='图片预览')
|
||||
def image_preview(self, obj):
|
||||
if obj.image:
|
||||
return format_html('<img src="{}" style="max-width: 400px; max-height: 200px; border-radius: 8px;" />', obj.image.url)
|
||||
elif obj.image_url:
|
||||
return format_html('<img src="{}" style="max-width: 400px; max-height: 200px; border-radius: 8px;" />', obj.image_url)
|
||||
return "暂无图片"
|
||||
|
||||
|
||||
class ScoreDimensionInline(admin.TabularInline):
|
||||
model = ScoreDimension
|
||||
extra = 1
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('competition', '0009_alter_carouselitem_id_alter_comment_id_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='homepageconfig',
|
||||
name='carousel1_title',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='homepageconfig',
|
||||
name='carousel2_title',
|
||||
),
|
||||
]
|
||||
@@ -9,9 +9,6 @@ class HomePageConfig(models.Model):
|
||||
|
||||
main_title = models.CharField(max_length=200, default='"创赢未来"云南2026创业大赛', verbose_name="主标题")
|
||||
|
||||
carousel1_title = models.CharField(max_length=200, default='"创赢未来"云南2026创业大赛', verbose_name="轮播图1标题")
|
||||
carousel2_title = models.CharField(max_length=200, default='"七彩云南创业福地"创业主题系列活动', verbose_name="轮播图2标题")
|
||||
|
||||
organizer = models.CharField(max_length=200, default='云南省人力资源和社会保障厅', verbose_name="主办单位")
|
||||
undertaker = models.CharField(max_length=200, default='云南省就业局', verbose_name="承办单位")
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from rest_framework import serializers
|
||||
from django.conf import settings
|
||||
from .models import Competition, CompetitionEnrollment, ScoreDimension, Project, ProjectFile, Score, Comment, HomePageConfig, CarouselItem
|
||||
from .models import Competition, CompetitionEnrollment, ScoreDimension, Project, ProjectFile, Score, Comment, HomePageConfig
|
||||
from shop.serializers import WeChatUserSerializer
|
||||
|
||||
|
||||
@@ -11,41 +11,16 @@ def _media_url(file_field):
|
||||
return None
|
||||
|
||||
|
||||
class CarouselItemSerializer(serializers.ModelSerializer):
|
||||
display_image = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = CarouselItem
|
||||
fields = ['id', 'carousel_type', 'image', 'image_url', 'display_image',
|
||||
'title', 'subtitle', 'status', 'status_color', 'date', 'location',
|
||||
'order', 'is_active']
|
||||
|
||||
def get_display_image(self, obj):
|
||||
return _media_url(obj.image) or obj.image_url
|
||||
|
||||
|
||||
class HomePageConfigSerializer(serializers.ModelSerializer):
|
||||
display_banner = serializers.SerializerMethodField()
|
||||
carousel1_items = serializers.SerializerMethodField()
|
||||
carousel2_items = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = HomePageConfig
|
||||
fields = ['id', 'banner_image', 'banner_image_url', 'display_banner',
|
||||
'main_title', 'carousel1_title', 'carousel2_title',
|
||||
'organizer', 'undertaker', 'carousel1_items', 'carousel2_items']
|
||||
|
||||
'main_title', 'organizer', 'undertaker']
|
||||
def get_display_banner(self, obj):
|
||||
return _media_url(obj.banner_image) or obj.banner_image_url
|
||||
|
||||
def get_carousel1_items(self, obj):
|
||||
items = CarouselItem.objects.filter(carousel_type='carousel1', is_active=True)
|
||||
return CarouselItemSerializer(items, many=True, context=self.context).data
|
||||
|
||||
def get_carousel2_items(self, obj):
|
||||
items = CarouselItem.objects.filter(carousel_type='carousel2', is_active=True)
|
||||
return CarouselItemSerializer(items, many=True, context=self.context).data
|
||||
|
||||
|
||||
class ScoreDimensionSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
|
||||
@@ -2,7 +2,7 @@ from django.urls import path, include
|
||||
from rest_framework.routers import DefaultRouter
|
||||
from .views import (
|
||||
CompetitionViewSet, ProjectViewSet, ProjectFileViewSet,
|
||||
ScoreViewSet, CommentViewSet, CarouselItemViewSet, get_homepage_config
|
||||
ScoreViewSet, CommentViewSet, get_homepage_config
|
||||
)
|
||||
from . import judge_views
|
||||
|
||||
@@ -12,7 +12,6 @@ router.register(r'projects', ProjectViewSet, basename='project')
|
||||
router.register(r'files', ProjectFileViewSet, basename='projectfile')
|
||||
router.register(r'scores', ScoreViewSet, basename='score')
|
||||
router.register(r'comments', CommentViewSet, basename='comment')
|
||||
router.register(r'carousel-items', CarouselItemViewSet, basename='carouselitem')
|
||||
|
||||
urlpatterns = [
|
||||
# 首页配置
|
||||
|
||||
@@ -3,12 +3,12 @@ from rest_framework.decorators import action, api_view, permission_classes
|
||||
from rest_framework.response import Response
|
||||
from django.db.models import Q
|
||||
from shop.utils import get_current_wechat_user
|
||||
from .models import Competition, CompetitionEnrollment, Project, ProjectFile, Score, Comment, ScoreDimension, HomePageConfig, CarouselItem
|
||||
from .models import Competition, CompetitionEnrollment, Project, ProjectFile, Score, Comment, ScoreDimension, HomePageConfig
|
||||
from .serializers import (
|
||||
CompetitionSerializer, CompetitionEnrollmentSerializer,
|
||||
ProjectSerializer, ProjectFileSerializer,
|
||||
ScoreSerializer, CommentSerializer, ScoreDimensionSerializer,
|
||||
HomePageConfigSerializer, CarouselItemSerializer
|
||||
HomePageConfigSerializer
|
||||
)
|
||||
|
||||
from rest_framework.pagination import PageNumberPagination
|
||||
@@ -28,22 +28,6 @@ def get_homepage_config(request):
|
||||
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
|
||||
class CarouselItemViewSet(viewsets.ModelViewSet):
|
||||
"""轮播图项目管理"""
|
||||
queryset = CarouselItem.objects.all()
|
||||
serializer_class = CarouselItemSerializer
|
||||
permission_classes = [permissions.AllowAny]
|
||||
filter_backends = [filters.SearchFilter]
|
||||
search_fields = ['title']
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = CarouselItem.objects.all()
|
||||
carousel_type = self.request.query_params.get('carousel_type')
|
||||
if carousel_type:
|
||||
queryset = queryset.filter(carousel_type=carousel_type)
|
||||
return queryset
|
||||
|
||||
|
||||
class StandardResultsSetPagination(PageNumberPagination):
|
||||
page_size = 10
|
||||
page_size_query_param = 'page_size'
|
||||
|
||||
@@ -255,11 +255,6 @@ UNFOLD = {
|
||||
"icon": "home",
|
||||
"link": reverse_lazy("admin:competition_homepageconfig_changelist"),
|
||||
},
|
||||
{
|
||||
"title": "轮播图管理",
|
||||
"icon": "image",
|
||||
"link": reverse_lazy("admin:competition_carouselitem_changelist"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user