我在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)
答案 0 :(得分:3)
您正在显示相关实体的span
(由于name
和get_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
。