admin 手机和用户名
All checks were successful
Deploy to Server / deploy (push) Successful in 16s

This commit is contained in:
jeremygan2021
2026-03-17 20:59:24 +08:00
parent de1e409447
commit 4d6f98080e
2 changed files with 82 additions and 12 deletions

View File

@@ -120,7 +120,7 @@ class OrderableAdminMixin:
@admin.register(Activity)
class ActivityAdmin(ModelAdmin):
list_display = ('title', 'author', 'banner_display', 'start_time', 'location', 'signup_count', 'is_visible', 'is_active', 'auto_confirm', 'created_at')
list_display = ('title', 'author_info_display', 'banner_display', 'start_time', 'location', 'signup_count', 'is_visible', 'is_active', 'auto_confirm', 'created_at')
list_filter = ('is_visible', 'is_active', 'auto_confirm', 'start_time')
search_fields = ('title', 'location', 'author__phone_number')
# autocomplete_fields = ['author'] # 暂时注释,避免环境不一致导致报错
@@ -141,6 +141,14 @@ class ActivityAdmin(ModelAdmin):
}),
)
@display(description="发布者 (手机号/昵称)")
def author_info_display(self, obj):
if not obj.author:
return "-"
phone = obj.author.phone_number or "无手机号"
nickname = obj.author.nickname or "无昵称"
return f"{phone} ({nickname})"
@display(description="Banner")
def banner_display(self, obj):
if obj.banner:
@@ -155,7 +163,7 @@ class ActivityAdmin(ModelAdmin):
@admin.register(ActivitySignup)
class ActivitySignupAdmin(ModelAdmin):
list_display = ('activity', 'user', 'signup_time', 'status_label', 'order_link')
list_display = ('activity', 'user_info_display', 'signup_time', 'status_label', 'order_link')
list_filter = ('status', 'signup_time', 'activity')
search_fields = ('user__nickname', 'user__phone_number', 'activity__title')
autocomplete_fields = ['activity', 'user']
@@ -172,6 +180,12 @@ class ActivitySignupAdmin(ModelAdmin):
)
readonly_fields = ('signup_time', 'signup_info_display')
@display(description="报名用户 (手机号/昵称)")
def user_info_display(self, obj):
phone = obj.user.phone_number or "无手机号"
nickname = obj.user.nickname or "无昵称"
return f"{phone} ({nickname})"
@display(description="报名信息")
def signup_info_display(self, obj):
import json
@@ -209,7 +223,7 @@ class ActivitySignupAdmin(ModelAdmin):
@admin.register(Topic)
class TopicAdmin(OrderableAdminMixin, ModelAdmin):
list_display = ('title', 'status', 'category', 'author', 'get_related_item', 'reply_count', 'view_count', 'is_pinned', 'created_at', 'order_actions')
list_display = ('title', 'status', 'category', 'author_info_display', 'get_related_item', 'reply_count', 'view_count', 'is_pinned', 'created_at', 'order_actions')
list_filter = ('status', 'category', 'is_pinned', 'created_at', 'related_product', 'related_service', 'related_course')
search_fields = ('title', 'content', 'author__nickname', 'author__phone_number')
autocomplete_fields = ['author', 'related_product', 'related_service', 'related_course']
@@ -218,6 +232,14 @@ class TopicAdmin(OrderableAdminMixin, ModelAdmin):
actions = ['reset_ordering', 'approve_topics', 'reject_topics']
list_editable = ('status', 'is_pinned', 'view_count')
@display(description="作者 (手机号/昵称)")
def author_info_display(self, obj):
if not obj.author:
return "-"
phone = obj.author.phone_number or "无手机号"
nickname = obj.author.nickname or "无昵称"
return f"{phone} ({nickname})"
@admin.action(description="批量通过审核")
def approve_topics(self, request, queryset):
rows_updated = queryset.update(status='published')
@@ -277,7 +299,7 @@ class TopicAdmin(OrderableAdminMixin, ModelAdmin):
@admin.register(Reply)
class ReplyAdmin(ModelAdmin):
list_display = ('short_content', 'topic', 'author', 'is_pinned', 'like_count', 'created_at')
list_display = ('short_content', 'topic', 'author_info_display', 'is_pinned', 'like_count', 'created_at')
list_filter = ('is_pinned', 'created_at')
search_fields = ('content', 'author__nickname', 'author__phone_number', 'topic__title')
autocomplete_fields = ['author', 'topic', 'reply_to']
@@ -295,6 +317,14 @@ class ReplyAdmin(ModelAdmin):
)
readonly_fields = ('created_at',)
@display(description="回复者 (手机号/昵称)")
def author_info_display(self, obj):
if not obj.author:
return "-"
phone = obj.author.phone_number or "无手机号"
nickname = obj.author.nickname or "无昵称"
return f"{phone} ({nickname})"
@display(description="点赞数")
def like_count(self, obj):
return obj.likes.count()

View File

@@ -1,5 +1,6 @@
from django.contrib import admin
from unfold.admin import ModelAdmin
from unfold.decorators import display
from .models import Competition, CompetitionEnrollment, ScoreDimension, Project, ProjectFile, Score, Comment
class ScoreDimensionInline(admin.TabularInline):
@@ -45,11 +46,20 @@ class CompetitionAdmin(ModelAdmin):
@admin.register(CompetitionEnrollment)
class CompetitionEnrollmentAdmin(ModelAdmin):
list_display = ['competition', 'user', 'role', 'status', 'created_at']
list_display = ['competition', 'user_info_display', 'role', 'status', 'created_at']
list_filter = ['competition', 'role', 'status']
search_fields = ['user__nickname', 'competition__title']
search_fields = ['user__nickname', 'user__phone_number', 'competition__title']
autocomplete_fields = ['user', 'competition']
actions = ['approve_enrollment', 'reject_enrollment']
@display(description="报名用户 (手机号/昵称)")
def user_info_display(self, obj):
if not obj.user:
return "-"
phone = obj.user.phone_number or "无手机号"
nickname = obj.user.nickname or "无昵称"
return f"{phone} ({nickname})"
def approve_enrollment(self, request, queryset):
queryset.update(status='approved')
approve_enrollment.short_description = "通过审核"
@@ -60,9 +70,10 @@ class CompetitionEnrollmentAdmin(ModelAdmin):
@admin.register(Project)
class ProjectAdmin(ModelAdmin):
list_display = ['id', 'title', 'competition', 'contestant', 'status', 'final_score', 'created_at']
list_display = ['id', 'title', 'competition', 'contestant_info_display', 'status', 'final_score', 'created_at']
list_filter = ['competition', 'status']
search_fields = ['id', 'title', 'contestant__user__nickname']
search_fields = ['id', 'title', 'contestant__user__nickname', 'contestant__user__phone_number']
autocomplete_fields = ['competition', 'contestant']
inlines = [ProjectFileInline]
readonly_fields = ['id', 'final_score']
@@ -79,17 +90,46 @@ class ProjectAdmin(ModelAdmin):
}),
)
@display(description="参赛人员 (手机号/昵称)")
def contestant_info_display(self, obj):
if not obj.contestant or not obj.contestant.user:
return "-"
user = obj.contestant.user
phone = user.phone_number or "无手机号"
nickname = user.nickname or "无昵称"
return f"{phone} ({nickname})"
@admin.register(Score)
class ScoreAdmin(ModelAdmin):
list_display = ['project', 'judge', 'dimension', 'score', 'created_at']
list_display = ['project', 'judge_info_display', 'dimension', 'score', 'created_at']
list_filter = ['project__competition', 'dimension']
search_fields = ['project__title', 'judge__user__nickname']
search_fields = ['project__title', 'judge__user__nickname', 'judge__user__phone_number']
autocomplete_fields = ['project', 'judge']
@display(description="评委 (手机号/昵称)")
def judge_info_display(self, obj):
if not obj.judge or not obj.judge.user:
return "-"
user = obj.judge.user
phone = user.phone_number or "无手机号"
nickname = user.nickname or "无昵称"
return f"{phone} ({nickname})"
@admin.register(Comment)
class CommentAdmin(ModelAdmin):
list_display = ['project', 'judge', 'content_preview', 'created_at']
list_display = ['project', 'judge_info_display', 'content_preview', 'created_at']
list_filter = ['project__competition']
search_fields = ['project__title', 'judge__user__nickname', 'content']
search_fields = ['project__title', 'judge__user__nickname', 'judge__user__phone_number', 'content']
autocomplete_fields = ['project', 'judge']
@display(description="评委 (手机号/昵称)")
def judge_info_display(self, obj):
if not obj.judge or not obj.judge.user:
return "-"
user = obj.judge.user
phone = user.phone_number or "无手机号"
nickname = user.nickname or "无昵称"
return f"{phone} ({nickname})"
def content_preview(self, obj):
return obj.content[:50] + '...' if len(obj.content) > 50 else obj.content