Значительная проблема с производительностью Django Admin - метки внешних ключей - PullRequest
0 голосов
/ 06 февраля 2019

У меня значительная проблема с производительностью Django Admin.

У меня есть модель сопоставления, в которой я сопоставляю первичные ключи 2 других режимов

В моем FundManagerMappingAdmin я пытаюсь представить внешний ключиз 2 таблиц с меткой из моделей внешнего ключа.

Базовые модели имеют размер около 4000 строк

Я испытываю низкую производительность при получении списка в админке, а также при редактировании иобновление

Может ли кто-нибудь указать на недостатки этого кода?

Есть ли лучший способ, пожалуйста?

Admin.py

@admin.register(ChampDwDimFundManagerMapping)
class FundManagerMappingAdmin(admin.ModelAdmin):

list_display = ['get_champ_fund_manager_id', 'get_evestment_name', 'get_sharepoint_name', ]

def get_champ_fund_manager_id(self, obj):
    return obj.fund_manager_id
get_champ_fund_manager_id.short_description = 'CHAMP Manager ID'

def get_evestment_name(self, obj):
    return obj.evestment_fund_manager_id.manager_name
get_evestment_name.short_description = 'Evestment Manager Name'

def get_sharepoint_name(self, obj):
    return obj.sharepoint_fund_manager_id.manager_name
get_sharepoint_name.short_description = 'Sharepoint Manager Name'

def get_form(self, request, obj=None, **kwargs):
    form = super(ChampFundManagerMappingAdmin, self).get_form(request, obj, **kwargs)
    form.base_fields['sharepoint_fund_manager_id'].label_from_instance = lambda obj: "{} {}".format(obj.final_publications_fund_manager_id, obj.manager_name)
    form.base_fields['evestment_fund_manager_id'].label_from_instance = lambda obj: "{} {}".format(obj.evestment_fundmanager_id_bk, obj.manager_name)
    return form

Models.py

class FundManagerMapping(models.Model):
    fund_manager_id = models.AutoField(db_column='FundManagerId', primary_key=True)  
    sharepoint_fund_manager_id = models.ForeignKey(SharePointFundManager, models.DO_NOTHING, db_column='SharePointFundManagerId')  
    evestment_fund_manager_id = models.ForeignKey(EvestmentFundManager, models.DO_NOTHING, db_column='eVestmentFundManagerId')  

class EvestmentFundManager(models.Model):
    evestment_fund_manager_id = models.AutoField(db_column='eVestmentFundManagerId', primary_key=True)  
    package_execution_id = models.IntegerField(db_column='PackageExecutionId')  
    evestment_fund_manager_id_bk = models.CharField(db_column='eVestmentFundManagerId_BK', max_length=50)  
    manager_name = models.CharField(db_column='ManagerName', max_length=255)  

class SharePointFundManager(models.Model):
    sharepoint_fund_manager_id = models.AutoField(db_column='SharePointFundManagerId', primary_key=True)  
    package_execution_id = models.IntegerField(db_column='PackageExecutionId')  
    research_fund_manager_id = models.CharField(db_column='ResearchFundManagerId', max_length=50, blank=True, null=True)  
    final_publications_fund_manager_id = models.CharField(db_column='FinalPublicationsFundManagerId', max_length=50, blank=True, null=True)  
    manager_name = models.CharField(db_column='ManagerName', max_length=255)  

1 Ответ

0 голосов
/ 06 февраля 2019

Вы показываете name связанных сущностей (из-за get_evestment_name и get_sharepoint_name) без объединения / предварительной выборки.Это означает, что для каждой отображаемой строки и каждого имени связанной сущности требуется django для выполнения запроса к базе данных.Вам нужно переопределить get_queryset() из ModelAdmin и использовать select_related, чтобы сказать django, что нужно присоединиться к этим сущностям с самого начала, чтобы не требовалось никаких дополнительных запросов для получения этих имен:

@admin.register(ChampDwDimFundManagerMapping)
class FundManagerMappingAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        return super().get_queryset(request).select_related(
            'sharepoint_fund_manager_id', 
            'evestment_fund_manager_id',
        )

Также вы не называете ForeignKey поля something_id.Это просто sharepoint_fund_manager, потому что то, что вы получаете, когда звоните fund_manager.sharepoint_fund_manager_id, это не идентификатор, а экземпляр SharePointFundManager.Странно звонить sharepoint_fund_manager_id.name.Идентификатор не имеет атрибута имени.Управляющий фондом имеет.

Кроме того, Django автоматически создает для вас свойство sharepoint_fund_manager_id, если вы вызываете поле sharepoint_fund_manager для доступа к простому внешнему ключу.

...