Django Admin的重大性能问题-外键标签

时间:2019-02-05 23:29:24

标签: python django django-models django-admin

我在Django Admin中遇到严重的性能问题。

我有一个映射模型,可以映射其他2种模式的主键

在我的FundManagerMappingAdmin中,我尝试用外键模型中的标签表示2个表的外键。

基础模型大约有4000行

在admin中检索列表,然后在进行编辑和更新时,我遇到了性能下降

有人可以指出这段代码的效率低下吗?

请问有更好的方法吗?

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 :(得分:3)

您正在显示相关实体的span(由于nameget_evestment_name)而没有加入/预取它们。这意味着对于您显示的每一行以及相关实体的每个名称,都需要django进行数据库查询。您需要覆盖get_sharepoint_name中的get_queryset()并使用ModelAdmin来告诉django从一开始就加入这些实体,这样就不需要任何其他查询来获得这些名称:

select_related

您也不会命名@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时得到的不是id,而是fund_manager.sharepoint_fund_manager_id的实例。叫SharePointFundManager很奇怪。 id没有名称属性。基金经理有。

此外,如果您调用字段sharepoint_fund_manager_id.name来访问普通外键,则Django会自动为您创建属性sharepoint_fund_manager_id