Django admin list page takes forever to load after overriding get_queryset method

巧了我就是萌 提交于 2020-07-03 13:15:08

问题


I have this model admin -

class NewsAdmin(ImageWidgetAdmin):
    image_fields = ['featured_image']
    list_per_page = 20
    list_display = ('heading', 'category', 'status', 'is_active', 'created_at', 'published_at',
                    'created_by', 'published_by')
    list_editable = ('category', 'status', 'is_active')
    list_filter = ('published_at', 'created_at', 'status', 'is_active', 'created_by',
                   'published_by',)
    search_fields = ('heading', 'category', 'tags', 'source')
    actions = [enable_object, disable_object, status_draft, status_private, status_public]
    actions_on_bottom = True

It only takes max 400ms to load. Here's the django-debug-toolbar image -

djdt image without get_queryset

But when I override the get_queryset method for language filtered objects -

    def get_queryset(self, request):
        queryset = super(NewsAdmin, self).get_queryset(request)
        return queryset.filter(language=request.LANGUAGE_CODE)

It takes around 17-18 seconds which is nuts!! Here's the django-debug-toolbar image -

djdt image with get_queryset

Even same this is happening for the front end queries as well! For details - I have database table with around 400k records and here's the model -

class News(BaseEntityBasicAbstract, HitCountMixin):
    NEWS_STATUS = (
        ('draft', _('Draft')),
        ('pending', _('Pending')),
        ('review', _('Review')),
        ('public', _('Public')),
        ('private', _('Private'))
    )
    backup = models.BooleanField(default=False)
    prev_id = models.BigIntegerField(null=True, blank=True)
    language = models.CharField(max_length=10, choices=LANGUAGES, default='bn')
    heading = models.CharField(max_length=255, null=True, blank=True,
                               verbose_name=_('News Heading'),
                               help_text=_('Provide a news heading/caption.'))
    sub_caption = models.TextField(max_length=255, null=True, blank=True,
                                   verbose_name=_('Summary'),
                                   help_text=_('Provide summary of the news.'))
    url = models.CharField(max_length=255, unique=True, verbose_name=_('URL/Slug/Link'),
                           help_text=_('Unique url for the news without whitspace.'))
    content = HTMLField(null=True, blank=True, verbose_name=_('Content'),
                        help_text=_('HTML content with texts, links & images.'))
    featured_image = models.FileField(upload_to=FilePrefix('news/'), null=True, blank=True,
                                      verbose_name=_('Featured Image'),
                                      help_text=_('Upload a featured image for news.'))
    image_caption = models.TextField(max_length=255, null=True, blank=True,
                                     verbose_name=_('Image Caption'),
                                     help_text=_('Provide a image caption.'))
    status = models.CharField(max_length=20, choices=NEWS_STATUS, default='pending',
                              verbose_name=_('News Status'),
                              help_text=_('Only public news can be seen on front end.'))
    source = models.ForeignKey(NewsSource, on_delete=models.SET_NULL, null=True, blank=True,
                               verbose_name=_('News Source'),
                               help_text=_('Select a news source.'))
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True,
                                 verbose_name=_('Category'),
                                 help_text=_('Select a news category.'))
    tags = tagulous.models.TagField(
        blank=True,
        to=Tags,
        verbose_name=_('News Tags'),
        help_text=_('Provide news tags separated with commas.')
    )
    published_at = models.DateTimeField(null=True, blank=True,
                                        verbose_name=_('Published At'))
    menu_items = GenericRelation(MenuItems, object_id_field='id',
                                 related_query_name='news_as_menu')
    hit_count_generic = GenericRelation(HitCount, object_id_field='object_pk',
                                        related_query_name='news_hit_count')
    created_by = models.ForeignKey(User, related_name='news_created_by',
                                   on_delete=models.SET_NULL, null=True, blank=True,
                                   verbose_name=_('Created By'))
    updated_by = models.ForeignKey(User, related_name='news_updated_by',
                                   on_delete=models.SET_NULL, null=True, blank=True,
                                   verbose_name=_('Last Updated By'))
    published_by = models.ForeignKey(User, related_name='news_published_by',
                                     on_delete=models.SET_NULL, null=True, blank=True,
                                     verbose_name=_('Published By'))
    deleted_by = models.ForeignKey(User, related_name='news_deleted_by',
                                   on_delete=models.SET_NULL, null=True, blank=True,
                                   verbose_name=_('Deleted By'))

I'm lost why is this happening! Please help me figure out the problem here!


回答1:


You are filtering on a field without an index. The bigger the table, the longer it takes as the database needs to scan each row. Alter your field definition to allow for an index and take care of migrations.

language = models.CharField(max_length=10, choices=LANGUAGES, default='bn' db_index=True)


来源:https://stackoverflow.com/questions/62146171/django-admin-list-page-takes-forever-to-load-after-overriding-get-queryset-metho

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!