django - 如何使用大规模数据限制 Django Admin.TabularInline 中的查询

标签 django python-2.7 django-models django-forms django-admin

我目前正在使用 admin.TabularInline 加载 50k 条数据记录,由于超时,页面未加载。我使用的是 Django 1.9 版,无法升级。

我已经尝试覆盖 get_queryset 以仅返回 10 条记录。

class RemDetailInline(admin.TabularInline):
    model = RemDetail
    fields = ('rem_name', 'ben_name', 'payout_amount', 
              'payout_currency', 'status','type', 'date_created')
    readonly_fields = ('rem_name', 'ben_name', 'payout_amount', 
                       'payout_currency', 'status', 'type', 'date_created')
    extra = 0
    max_num = 0
    show_change_link = True
    ordering = ['-date_created',]

    def get_queryset(self, request):
        queryset = super(RemDetailInline, self).get_queryset(request)
        ids = queryset.order_by('-id').values('pk')[:10] # limit 10
        qs = RemDetailInline.objects.filter(pk__in=ids).order_by('-id')
        return qs

我希望输出返回 10 条记录,而不是由于高容量(50k 条记录)导致的页面超时

最佳答案

好的,这次我能够设计一个可行的解决方案, 然后我能够通过专用的 mixin 将它提炼成易于重用的东西:

你只需要在你的内联定义中使用这个mixin:

from django.forms.models import _get_foreign_key
from django.contrib import messages

class LimitResults_InlineMixin:
    """
    Limits the number of results processed & displayed by an Inline to 'list_max_show_all' records
    Prevents bloating of page loading time when many records
    list_max_show_all is by default set to 50

    Use:
        class MyInline(LimitResults_InlineMixin, admin.TabularInline):
            list_max_show_all=25
            <rest of your Inline definition>

    REMINDER: LimitResults_InlineMixin has to be declared before 'admin.TabularInline'
    """

    list_max_show_all=50

    def get_queryset(self, request):
        queryset = super().get_queryset(request)

        fk=_get_foreign_key(self.parent_model, self.model)
        queryset = queryset.filter(**{fk.name: request.resolver_match.kwargs['object_id']})

        if queryset.count() > self.list_max_show_all:
            my_ids = [i for i in queryset.defer().values_list('id', flat=True)]
            my_ids = my_ids[:self.list_max_show_all]

            queryset = queryset.filter(id__in=my_ids)
            messages.warning(request,
                                     f"The number of {self.model.__name__} objects displayed in inline has been limited to {self.list_max_show_all} items")

        return queryset

关于django - 如何使用大规模数据限制 Django Admin.TabularInline 中的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56272438/

相关文章:

python - 我们如何从Python中的glyph id获取unicode?

django - 如何通过多对多字段中的对象(完全匹配)过滤 django 模型?

django - django 模板中的两个外键和一个值

django - 如何定义 APIView 的 url?

python - Django - DateTimeField 收到一个天真的日期时间

Python IDLE 无法工作,因为缺少 python.exe

python - 从单词列表中创建句子 x 次

python - Django MultiWidget 电话号码字段

python - 在 Django 中连接字段值

python - Django Web App 通过 Heroku Connect 与 Salesforce 集成