繁体   English   中英

Django非常大的反向ForeignKey查询

[英]Django very large reverse ForeignKey query

我正在使用Django admin来过滤其反向ForeignKey对象字段值上的对象。 App有一个ForeignKeyContact ,我正在尝试按Django管理员中的Apps类别过滤Contacts 问题是查询非常大,并且出现超时错误。 大约有30万个Contact对象和1M的Apps。 在Django管理员中,每页有500个结果。 添加数据库索引和prefetch_related。 我还应该做些什么来优化Django admin? 我正在使用sqlite db。

编码:

class App(models.Model):
    contact = models.ForeignKey('Contact', related_name='apps', null=True)
    category = models.TextField(blank=True, null=True, db_index=True)
    store = models.IntegerField(choices=STORE_TYPES, db_index=True)

    class Meta:
        index_together = [
            ['category', 'store'],
        ]

# admin:

class ContactAdmin(admin.ModelAdmin):
    list_filter = (
        AppCategory,
    )

    def queryset(self, request):
        return super(ContactAdmin, self).queryset(request).prefetch_related(
            'apps',
            'to_contact',
        )

# the main list_filter that is causing troubles:

class AppCategory(admin.SimpleListFilter):
    title = 'app category'
    parameter_name = 'app_category'

def lookups(self, request, modelAdmin):

    return [
        ('Action', 'Action'),
        ('Adventure', 'Adventure'),
        ('Arcade', 'Arcade'),
        ('Board', 'Board'),
        ('Books', 'Books'),
        ('Books & Reference', 'Books & Reference'),
        ('Business', 'Business'),
        ('Card', 'Card'),
        ('Casino', 'Casino',),
        ('Casual', 'Casual'),
        ('Catalogs', 'Catalogs'),
        ('Comics', 'Comics'),
        ('Communication', 'Communication'),
        ('Education', 'Education'),
        ('Educational', 'Educational'),
        ('Entertainment', 'Entertainment'),
        ('Family', 'Family'),
        ('Finance', 'Finance'),
        ('Food & Drink', 'Food & Drink'),
        ('Games', 'Games'),
        ('Health & Fitness', 'Health & Fitness'),
        ('Libraries & Demo', 'Libraries & Demo'),
        ('Lifestyle', 'Lifestyle'),
        ('Media & Video', 'Media & Video'),
        ('Medical', 'Medical'),
        ('Music', 'Music'),
        ('Music & Audio', 'Music & Audio'),
        ('Navigation', 'Navigation'),
        ('News', 'News'),
        ('News & Magazines', 'News & Magazines'),
        ('Personalization', 'Personalization'),
        ('Photo & Video', 'Photo & Video'),
        ('Photography', 'Photography'),
        ('Productivity', 'Productivity'),
        ('Puzzle', 'Puzzle'),
        ('Racing', 'Racing'),
        ('Reference', 'Reference'),
        ('Role Playing', 'Role Playing'),
        ('Shopping', 'Shopping'),
        ('Simulation', 'Simulation'),
        ('Social', 'Social'),
        ('Social Networking', 'Social Networking'),
        ('Sports', 'Sports'),
        ('Strategy', 'Strategy'),
        ('Tools', 'Tools'),
        ('Transportation', 'Transportation'),
        ('Travel', 'Travel'),
        ('Travel & Local', 'Travel & Local'),
        ('Trivia', 'Trivia'),
        ('Utilities', 'Utilities'),
        ('Weather', 'Weather'),
        ('Word', 'Word')
    ]

def queryset(self, request, queryset):
    if not self.value():
        return queryset
    else:
        qs = queryset.filter(
            apps__category=self.value()
        )
        return qs

我找到了答案。 如果您要过滤一个反向的ForeignKey关系(在这种情况下为apps__category ),则一切正常。 但是我忘了提一下,我在Django管理页面的右侧合并了两个过滤器-另一个也是反向的ForeignKey - apps__store 执行此操作时,将执行两个完全相同的INNER JOIN ,这将导致服务器超时。 当我分别使用这些过滤器时,一切正常。

参见: https : //code.djangoproject.com/ticket/16554

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM