Python Django-在Django admin中显示记录,同时显示组、最大计数和时间戳

Python Django-在Django admin中显示记录,同时显示组、最大计数和时间戳,python,python-3.x,django,django-models,django-3.0,Python,Python 3.x,Django,Django Models,Django 3.0,这是我的密码 models.py(应用程序:文章) admin.py(应用程序:文章) 我的数据库记录当前如下所示: 在django admin中,我希望以这种方式显示所有这些记录 未解决的查询应该首先显示(我可以通过使用排序=['solved_status']实现) < > < (i)未解决的< /强>和(ii)报告最高的次数< /强>应该是第一个(这里A1:因为它被报告 3 < /强>次。不要考虑A2,因为在最后的记录中,它被认为是解决的。 同一篇文章中相同原因的最高数量(在这里仇恨语音<

这是我的密码

models.py(应用程序:文章)

admin.py(应用程序:文章)

我的数据库记录当前如下所示:

在django admin中,我希望以这种方式显示所有这些记录

  • 未解决的查询应该首先显示(我可以通过使用
    排序=['solved_status']
    实现)
  • < > < <强>(i)未解决的< /强>和<强>(ii)报告最高的次数< /强>应该是第一个(这里A1:因为它被报告<强> 3 < /强>次。不要考虑A2,因为在最后的记录中,它被认为是解决的。
  • 同一篇文章中相同原因的最高数量(在这里<强>仇恨语音< /强>是2次,所以它应该先出现,然后<强>垃圾邮件< /强>应该出现> <强>注:< /强>不要考虑<强>垃圾邮件< /强> 4次,因为我们必须先完成条件2。
  • <> LI>首先报告的文章应根据 DeaTime首先显示(<强> id 8:<强> >,然后<强> ID 1 < /强> <强>注:< /强>不要认为<强> ID 7 < /强>最早,因为我们必须先完成条件1, 2和3。
  • 如果剩余记录不符合123中的任何条件,则首先生成的报告应根据日期时间首先显示
  • 因此,最终的表格应该如下所示:

    现在,我们可以看到

  • 当已解决的查询移到最后时,满足了第一个条件
  • 我们的第二个条件得到满足,因为a1被移动到顶部,这是提交报告最多的文章
  • 我们满足了第三个条件,因为仇恨言论是文章a1中报告最多的原因
  • 我们的第四个条件得到满足,Id:8移到顶部,因为考虑到DateTime字段,此报告是在Id:1之前生成的
  • 我们满足了第五个条件,因为id:5id:3没有任何共同点,但由于id:5在前面,所以它应该在前面

  • 我尝试使用annotate,我认为它可以解决我的部分疑问,但它不断给我带来错误和疑问,但仍未解决。我尝试了很长一段时间,任何帮助都是值得的。提前感谢:)

    一些窗口函数注释应该能够实现所描述的顺序:

    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)
    

    @TomWojcik编辑:我不需要亚马逊的查询。我只想知道如何在Django admin中解决这些复杂的查询。我们可以使用
    分组或
    分区以及
    计数
    [SQL术语]等。。全部加在一起。亚马逊写这篇文章只是为了举个例子。你的回答让我在这个问题上取得了显著的进步。但我仍然面临一些问题。让我来解释第一个问题:你可以看到我在**同一**文章中写了最多的相同原因。看见(见第一和第二条记录)我有两条记录,报告了两篇不同的文章。但两者的原因是相同的。因此,根据第4点
    首先报告的文章应首先显示
    。但事实并非如此。我认为这是因为它计数的报告也解决了,或者它是第一次划分的。第2个问题:我看到的所有行都使用<代码>计数(*)<代码>读取第二点:<代码>不要考虑A2,因为在最后的记录中,它被视为已解决
    在达到第一点后,不应考虑已解决的报告。它们只应显示。没有其他问题。第三个问题:查看前4项记录。这里,2篇文章每篇报道2次,所有这4条记录都给出了相同的理由。现在,它应该按创建日期进行排序。但事实并非如此。是的,我误解了已解决的状态,认为它将适用于整篇文章和报告,因此我现在通过从窗口函数中过滤已解决的报告来纠正这一点。我认为这也解决了其他问题,但我仍然不完全清楚。一篇文章中所有未解决的报告应该一起出现,对吗?啊,有趣的是,我不认为postgres上存在对
    filter
    COUNT(*)的限制,但对于指定字段,我认为
    id
    可能是最简单的。我将编辑答案,并在管理中包括添加
    count\u by\u article
    count\u by\u article\u和\u reason
    的代码。
    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)
    
    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)