2013-05-26 13 views
6

我的一個Django的網站具有以下數據庫模型: 在Django應用程序「常見」:Django管理變化的形式加載很慢

class Collection(models.Model): 
    name = models.CharField(max_length = 255, unique = True) 
    _short_name = models.CharField(db_column="short_name", max_length = 32, blank=True) 

class Particle(models.Model): 
    content = models.TextField(blank=False) 
    owner = models.ForeignKey(Collection) 
    order = models.IntegerField(null=True, blank=True) 

在Django應用程序「情景喜劇」:

class Media(models.Model): 
    name = models.CharField(max_length = 248) 
    _short_name = models.CharField(db_column="short_name", max_length = 32, blank=True) 
    capital = models.CharField(max_length = 1) 
    description = models.TextField(blank=True) 
    progress = models.CharField(max_length = 32, blank=True, null=True) 

class Relation(models.Model): 
    name = models.CharField(max_length = 128) 
    _short_name = models.CharField(db_column="short_name", max_length = 32, blank=True) 
    description = models.TextField(blank=True) 
    parent = models.ForeignKey('self', blank=True, null=True) 
    order = models.IntegerField(blank=True, null=True) 
    particle = models.ForeignKey(Particle, blank=True, null=True) 
    media = models.ForeignKey(Media, blank=True, null=True) 

在簡而言之,模型類Relation有3個外鍵給其他表。 問題是,當我使用Django Admin更改單個關係時,頁面(change_form)加載得相當緩慢。 後來,我改變了模型類的關係如下:

class Relation(models.Model): 
    name = models.CharField(max_length = 128) 
    _short_name = models.CharField(db_column="short_name", max_length = 32, blank=True) 
    description = models.TextField(blank=True) 
    order = models.IntegerField(blank=True, null=True) 
    parent_id = models.IntegerField(blank=True, null=True) 
    particle_id = models.IntegerField(blank=True, null=True) 
    media_id = models.IntegerField(blank=True, null=True) 

修改改變外鍵IntegerFields,所以它禁用了一些Django的ORM系統裏面的魔法,現在的變化形式的頁面加載的真快。 我的問題是,什麼是「django orm裏面的殘疾魔法師」?有什麼可能導致問題?

回答

9

這不是django Orm的魔力。它是Form的魔法。 在模型中創建外鍵時,在ModelForm中,ModelChoiceField會創建具有所有ForeignKey模型選項的模型。而django Admin使用Form的所有屬性來創建HTML。 所以使用這段代碼。

from django import forms 
class RelationForm(forms.ModelForm): 
    parent = forms.ChoiceField(required=False, 
           choices=Relation.objects.values_list('id', 'name')) 
    particle = forms.ChoiceField(required=False, 
           choices=Particle.objects.values_list('id', 'content')) 
    media = forms.ChoiceField(required=False, 
           choices=Media.objects.values_list('id', 'name')) 

    class Meta: 
     model = Relation 

在ADMIS網站

from django.contrib import admin 
class RelationAdmin(admin.ModelAdmin): 
    form = RelationForm 
    model = Relation 

您也可以緩存的選擇傳遞的形式。

+0

非常感謝!它工作,現在我可以再次使用ForeignKey,它更方便。 – Brent81

3

我願意打賭問題是由於您的ForeignKey。默認情況下,django爲每個外鍵呈現一個<select>元素。

如果你有成千上萬的行,這很容易開始膨脹你的HTML/DOM,我注意到瀏覽器開始廢話在一個<select>標記呈現的20K項目。

要修復它,請查看覆蓋您的管理員表單,而不是使用默認的小部件。

12

在admin.py

from django.contrib import admin 

class RelationAdmin(admin.ModelAdmin): 
     raw_id_fields = ('Media','Particle',) 

admin.site.register(Relation, RelationAdmin) 

這帶來了形式一個可愛的小UI元素,大大提高性能,因爲它沒有加載在選擇框中的選項數量巨大。

+1

謝謝!這個小技巧讓我的管理網站變得更加實用! – yairchu

+1

有時你不想編輯管理表單中的字段,只需查看它們,還可以添加'readonly_fields =('Media','Particle',''' –

0

如果外鍵模型記錄太多,它可能會凍結您的編輯表單。 開始的最佳方式是限制應該在表單上顯示的字段,並逐漸/逐個添加其他字段,檢查哪個字段使表單變慢。

from django.contrib import admin 
class RelationAdmin(admin.ModelAdmin): 
     fields = ('name',) 
admin.site.register(Relation, RelationAdmin) 

然後,在添加導致問題的字段(例如,媒體,表格會再次凍結。因此,如果你仍然需要表單上的這個字段,你可以使用Vishal Shah的答案raw_id_fields =('Media',)

0

在我的情況下,緩慢主要是由於過時的django-debug-toolbar(v1.7)引起的。 debug_toolbar.middleware.DebugToolbarMiddleware會導致管理頁面加載的字面需要20分鐘,如果它包含具有幾百個選項的ForeignKey字段。將工具欄升級到v1.8解決了所有問題。也許這有助於某人。