Django- 将 django-admin 中的记录与组、最大计数和时间戳一起显示

aji*_*hod 5 python django django-models python-3.x django-3.0

这是我的代码

模型.py(应用程序:文章)

from django.contrib.auth.models import User

class Article(models.Model):
    # code...
    url_title = models.CharField(max_length=80, unique=True, db_index=True)


HATE_SPEECH = 'HS'
SPAM = 'SP'
FAKE_INFO = 'FI'

REPORT_REASON = (
    (FAKE_INFO, 'Fake Information'),
    (HATE_SPEECH, 'Hate Speech'),
    (SPAM, 'Spam'))

class Report(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    article_id = models.ForeignKey(Article, on_delete=models.PROTECT)
    user_id = models.ForeignKey(User, on_delete=models.PROTECT)
    reason = models.CharField(max_length=2, choices=REPORT_REASON)
    solved_status = models.BooleanField(default=False)
    date_created = models.DateTimeField(auto_now_add=now)
Run Code Online (Sandbox Code Playgroud)

admin.py(应用:文章)

class ArticleAdmin(admin.ModelAdmin):
    pass
    # code...

class ReportAdmin(admin.ModelAdmin):
    list_display = ('id', 'article_id', 'user_id', 'reason', 'solved_status', 'date_created')

admin.site.register(Article, ArticleAdmin)
admin.site.register(Report, ReportAdmin)
Run Code Online (Sandbox Code Playgroud)

我的数据库记录目前看起来像这样:

在此处输入图片说明

django admin 中,我想以这种方式显示所有这些记录。

  1. 未解决的查询应首先显示(我可以使用它来实现ordering = ['solved_status']
  2. 这是文章(我)没有得到解决(二)报告的次数最多的应该是第一位的(这里的文章A1:因为它是报道3。次不考虑A2,因为在过去的记录,它被认为是解决
  3. 同一文章中相同原因的最高次数(此处仇恨言论出现 2 次,因此应先出现,然后再出现垃圾邮件注意:不要将垃圾邮件视为 4 次,因为我们必须先满足条件 2。
  4. 最先上报的文章应该根据DateTime最先显示。(id: 8首先被创建,然后是id 1注意:不要认为id 7是最老的,因为我们必须首先满足条件 1、2 和 3。
  5. 如果剩余的记录符合没有条件的从123,这是首次提出的报告应根据显示第一日期时间

所以,最终的表格应该是这样的:

在此处输入图片说明

现在,我们可以看到

  1. 当解决的查询移到最后时,我们的第一个条件得到满足。
  2. 我们的第二个条件得到满足,因为a1 被移到顶部,成为报告最高的文章。
  3. 我们的第三个条件得到满足,因为仇恨言论是第a1条中提出的最高报告的原因。
  4. 我们的第四个条件满足,因为Id: 8移到顶部,因为考虑到 DateTimeField,此报告是在id: 1之前制作的。
  5. 我们的第五个条件得到满足,因为id:5id:3没有任何共同点,但是因为id:5是在先的,所以它应该在前。

我尝试使用此链接使用注释,我认为这可以解决我的部分疑问,但它不断给我错误和疑问,但尚未解决。我已经尝试了很长时间,任何帮助都是可观的。提前致谢 :)

azu*_*ndo 1

一些窗口函数注释应该启用所描述的排序:

from django.db.models import F, Count, Window, Q

class ReportAdmin(admin.ModelAdmin):

    list_display = ('id', 'article_id', 'user_id', 'reason', 'solved_status', 'date_created',
                    'count_by_article', 'count_by_article_and_reason')

    def get_queryset(self, request):
        return super().get_queryset(request).annotate(
            count_by_article=Window(
                expression=Count('id', filter=Q(solved_status=False)),
                partition_by=F('article_id')
            ),
            count_by_article_and_reason=Window(
                expression=Count('id', filter=Q(solved_status=False)),
                partition_by=[F('article_id'), F('reason')],
            ),
            earliest_report_by_article=Window(
                expression=Min('date_created', filter=Q(solved_status=False)),
                partition_by=[F('article_id')],
            ),
            earliest_report_by_article_and_reason=Window(
                expression=Min('date_created', filter=Q(solved_status=False)),
                partition_by=[F('article_id'), F('reason')],
            ),
        ).order_by('solved_status', '-count_by_article', 'earliest_report_by_article', 'article_id',
                   '-count_by_article_and_reason', 'earliest_report_by_article_and_reason',
                   'reason', 'date_created')

    def count_by_article(self, obj):
        return obj.count_by_article

    def count_by_article_and_reason(self, obj):
        return obj.count_by_article_and_reason


admin.site.register(Report, ReportAdmin)
Run Code Online (Sandbox Code Playgroud)