Django admin list_display 使用外键时异常缓慢
姜戈 1.2.5 Python:2.5.5
我的运动模型管理列表速度非常慢(400 条记录需要 5 分钟)。它在一秒钟左右就恢复了,直到我们得到了 400 场比赛、50 支球队和 2 项运动。
我已经以一种糟糕的方式修复了它,所以我想看看是否有人以前见过这个。我的应用程序如下所示:
models:
Sport( models.Model )
name
Venue( models.Model )
name
Team( models.Model )
name
Fixture( models.Model )
date
sport = models.ForeignKey(Sport)
venue = models.ForeignKey(Venue)
TeamFixture( Fixture )
team1 = models.ForeignKey(Team, related_name="Team 1")
team2 = models.ForeignKey(Team, related_name="Team 2")
admin:
TeamFixture_ModelAdmin (ModelAdmin)
list_display = ('date','sport','venue','team1','team2',)
如果我从 list_display 中删除任何外键,那么速度很快。一旦我添加任何外键,速度就会变慢。
我通过使用非外键但在模型初始化中计算它们来修复它,这样就可以了:
models:
TeamFixture( Fixture )
team1 = models.ForeignKey(Team, related_name="Team 1")
team2 = models.ForeignKey(Team, related_name="Team 2")
sport_name = ""
venue_name = ""
team1_name = ""
team2_name = ""
def __init__(self, *args, **kwargs):
super(TeamFixture, self).__init__(*args, **kwargs)
self.sport_name = self.sport.name
self.venue_name = self.venue.name
self.team1_name = self.team1.name
self.team2_name = self.team2.name
admin:
TeamFixture_ModelAdmin (ModelAdmin)
list_display = ('date','sport_name','venue_name','team1_name','team2_name',)
所有其他模型的管理都很好,目前有几千条记录,并且实际站点中的所有视图都运行良好。
Django 1.2.5
Python: 2.5.5
My admin list of a sports model has just gone really slow (5 minutes for 400 records). It was returning in a second or so until we got 400 games, 50 odd teams and 2 sports.
I have fixed it in an awful way so I'd like to see if anyone has seen this before. My app looks like this:
models:
Sport( models.Model )
name
Venue( models.Model )
name
Team( models.Model )
name
Fixture( models.Model )
date
sport = models.ForeignKey(Sport)
venue = models.ForeignKey(Venue)
TeamFixture( Fixture )
team1 = models.ForeignKey(Team, related_name="Team 1")
team2 = models.ForeignKey(Team, related_name="Team 2")
admin:
TeamFixture_ModelAdmin (ModelAdmin)
list_display = ('date','sport','venue','team1','team2',)
If I remove any foreign keys from list_display then it's quick. As soon as I add any foreign key then slow.
I fixed it by using non foreign keys but calculating them in the model init so this works:
models:
TeamFixture( Fixture )
team1 = models.ForeignKey(Team, related_name="Team 1")
team2 = models.ForeignKey(Team, related_name="Team 2")
sport_name = ""
venue_name = ""
team1_name = ""
team2_name = ""
def __init__(self, *args, **kwargs):
super(TeamFixture, self).__init__(*args, **kwargs)
self.sport_name = self.sport.name
self.venue_name = self.venue.name
self.team1_name = self.team1.name
self.team2_name = self.team2.name
admin:
TeamFixture_ModelAdmin (ModelAdmin)
list_display = ('date','sport_name','venue_name','team1_name','team2_name',)
Administration for all other models are fine with several thousand records at the moment and all views in the actual site is functioning fine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这让我发疯。 list_select_lated 设置为 True,但是在 list_display 中向 User 添加外键会在管理中的每一行生成一个查询,这会使列表变慢。 Select_lated 为 True,因此 Django 管理员不应在每一行上调用此查询。
到底是怎么回事 ?
It's driving me crazy. list_select_related is set to True, however adding a foreign key to User in the list_display generates one query per row in the admin, which makes the listing slow. Select_related is True, so the Django admin shouldn't call this query on each row.
What is going on ?
我首先要寻找的是数据库调用。如果您不应该这样做,请安装 django-debug-toolbar。这个很棒的工具可以让您检查为当前请求完成的所有 SQL 查询。我想他们有很多。如果您查看它们,您就会知道在哪里寻找问题。
我自己也遇到过一个问题:当模型的 __unicode__ 方法使用外键时,会导致每个实例一次数据库命中。我知道有两种方法可以解决这个问题:
select_lated
,这通常是您最好的选择。save
方法以相应地更新此字符串。The first thing I would look for, are the database calls. If you shouldn't have done that already, install django-debug-toolbar. That awesome tool lets you inspect all sql queries done for the current request. I assume there are lots of them. If you look at them, you will know where to look for the problem.
One problem I myself have run into: When the
__unicode__
method of a model uses a foreign key, that leads to one database hit per instance. I know of two ways to overcome this problem:select_related
, which usually is your best bet.__unicode__
return a static string and override thesave
method to update this string accordingly.这是 django admin 和外键的一个非常老的问题。这里发生的情况是,每当您尝试加载一个对象时,它都会尝试获取该外键的所有对象。假设您正在尝试加载一些球队的赛程(假设球队数量约为 100 支),它将继续一次性包含所有 100 支球队。您可以尝试使用
raw_fields
来优化它们。这样做的目的是,不必一次调用所有内容,而是限制调用次数,并确保仅在触发事件时(即,当您选择团队时)才进行调用。如果这看起来有点像 UI 混乱,您可以尝试使用此类:
只需确保正确继承该类即可。我猜测类似
TeamFixture_ModelAdmin (ImproveRawIdFieldsForm)
。这很可能会给你的 django 管理带来相当酷的性能提升。This is a very old problem with django admin and foreign keys. What happens here is that whenever you try to load an object it tries to get all the objects of that foreign key. So lets say you are trying to load a fixture with a some teams (say the number of teams is about 100), its going to keep on including all the 100 teams in one go. You can try to optimize them by using something called as
raw_fields
. What this would do is instead of having to calling everything at once, it will limit the number of calls and make sure that the call is only made when an event is triggered (i.e. when you are selecting a team).If that seems a bit like a UI mess you can try using this class:
Just make sure that you inherit the class properly. I am guessing something like
TeamFixture_ModelAdmin (ImproveRawIdFieldsForm)
. This will most likely give you a pretty cool performance boost in your django admin.我通过将
list_select_lated
设置为相关模型字段列表而不是仅True
解决了我的问题I fixed my problem by setting
list_select_related
to the list of related model fields instead of justTrue