Django admin + autocomplete_light用于具有大型数据集的多对多字段

时间:2015-02-03 19:30:23

标签: python django django-autocomplete-light

Django版本:1.7
autocomplete_light版本:2.0

我有多对多的关系:订阅< - > 应用程序,其中每个应用程序可以属于多个订阅,每个订阅可以包含多个应用程序。 订阅数量预计将在数百个之前,而申请数量约为150万。

使用Django Admin来管理订阅及其应用程序会非常棒,并且正如Stackoverflow所建议的那样,将autocomplete_light用于大型数据集。 下面是我提出的代码,但它接口尝试一次加载AppMetadata的所有1.5百万条记录并挂起浏览器。 请指教。

# model.py
class AppMetadata(models.Model):
    package_key = models.IntegerField(primary_key=True)
    title = models.CharField(max_length=500)
    package = models.CharField(max_length=400)

class Subscription(models.Model):
    name = models.CharField(max_length=256, unique=True)
    is_active = models.BooleanField('active', default=True)

class SubscriptionApp(models.Model):
    subscription_key = models.ForeignKey(to=Subscription, on_delete=models.DO_NOTHING)
    package_key = models.ManyToManyField(to=AppMetadata, db_column='package_key')

# autocomplete_light_registry.py
class AppMetadataAutocomplete(autocomplete_light.AutocompleteModelBase):
    model = AppMetadata
    search_fields = ('title', 'package')
    choices = AppMetadata.objects.all()
    limit_choices = 20
autocomplete_light.register(AppMetadataAutocomplete)

class SubscriptionAppAutocomplete(autocomplete_light.AutocompleteGenericBase):
    model = SubscriptionApp
    choices = (
            Subscription.objects.all(),
            AppMetadata.objects.all(),
    )
    search_fields = (
            ('^name', ),
            ('title', 'package'),
    )
    limit_choices = 20
autocomplete_light.register(SubscriptionAppAutocomplete)

class SubscriptionAutocomplete(autocomplete_light.AutocompleteModelBase):
    model = Subscription
    choices = Subscription.objects.all()
    search_fields = ('name', )
    limit_choices = 20
autocomplete_light.register(SubscriptionAutocomplete)

# admin.py
class SubscriptionAppInline(admin.TabularInline):
    model = SubscriptionApp

class SubscriptionAdmin(admin.ModelAdmin):
    form = autocomplete_light.modelform_factory(model=Subscription)
    inlines = [SubscriptionAppInline]
admin.site.register(Subscription, SubscriptionAdmin)

# settings.py
INSTALLED_APPS = (
    'autocomplete_light',
    'django.contrib.admin',
    ...
...

# urls.py
urlpatterns = patterns(
    ...
    # last record
    url(r'^autocomplete/', include('autocomplete_light.urls')),
)

1 个答案:

答案 0 :(得分:0)

我想出了一个妥协的解决方案。从上面的代码中,我删除了 SubscriptionAutocomplete 并重写了 admin.py 类,如下所示:

@admin.register(SubscriptionApp)
class SubscriptionAppAdmin(admin.ModelAdmin):
    form = autocomplete_light.modelform_factory(model=SubscriptionApp)

class SubscriptionAppInline(admin.TabularInline):
    model = SubscriptionApp

@admin.register(Subscription)
class SubscriptionAdmin(admin.ModelAdmin):
    model = Subscription
    ordering = ('name',)