如何在Django Admin中筛选最新修订的法律条目?
问题:Django Admin中筛选最新修订的法律条目
模型关联关系
- 一个
Law模型对应多个Version(版本) - 一个
Version对应多个Translation(译文) - 一个
Translation对应多个注释
我创建了Law的代理模型LatestAmendedLaws,希望在Django Admin中展示关联译文有最新创建/更新记录的法律条目,但当前代码无法实现预期效果。
原Admin代码
@admin.register(LatestAmendedLaws) class LatestAmendedLawsAdmin(admin.ModelAdmin): list_display = ("id", "rs_number", "created") def get_queryset(self, request): latest_translation_datetime = Translation.objects.latest("created").created return ( super() .get_queryset(request) .filter(created__gte=latest_translation_datetime) )
问题原因
当前代码基于Law自身的created字段筛选,而实际需要根据法律条目关联的译文的最新创建/更新时间来筛选。
模型代码补充
class Law(Timestamped): ... class LatestAmendedLaws(Law): class Meta: proxy = True verbose_name = "Latest Amended Law" class Version(Timestamped): law = models.ForeignKey( 'Law', related_name='versions', ) version_date = models.DateField( verbose_name=_("Version Date"), ) class Translation(Timestamped): law_version = models.ForeignKey( 'Version', related_name='translations', ) ...
解决方案
通过关联查询获取每个法律条目对应的最新译文时间,再以此为依据筛选并展示:
from django.db.models import Subquery, OuterRef, Max from django.utils import timezone @admin.register(LatestAmendedLaws) class LatestAmendedLawsAdmin(admin.ModelAdmin): list_display = ("id", "rs_number", "created", "latest_translation_time") def get_queryset(self, request): # 子查询:获取每个法律对应的最新译文创建时间 latest_trans_subquery = Translation.objects.filter( law_version__law=OuterRef('pk') ).values('law_version__law').annotate( latest_created=Max('created') ).values('latest_created') queryset = ( super() .get_queryset(request) .annotate( latest_translation_time=Subquery(latest_trans_subquery) ) # 筛选存在译文更新记录的法律,可根据需求调整条件(比如仅保留最近7天更新的) .filter(latest_translation_time__isnull=False) # 按最新译文时间倒序排列 .order_by('-latest_translation_time') ) # 示例:仅展示最近7天有译文更新的法律 # queryset = queryset.filter(latest_translation_time__gte=timezone.now() - timezone.timedelta(days=7)) return queryset def latest_translation_time(self, obj): return obj.latest_translation_time latest_translation_time.short_description = "最新译文更新时间"
代码说明
- 用
Subquery和Max聚合函数,精准获取每个Law关联的所有译文里的最新created时间 - 通过
annotate给法律对象添加latest_translation_time字段,支持筛选和列表展示 - 可灵活调整筛选条件,比如限定时间范围、仅保留有译文的法律等
- 在
list_display中新增latest_translation_time,方便在Admin列表直接查看更新时间
内容的提问来源于stack exchange,提问作者Mahdi Jafari
相关产品推荐
相关产品推荐

