2013-03-04 25 views
9

list_display'da bir yabancı anahtar alanı içeren bir ModelAdmin sınıfım var. Ancak bu modelin yönetici listesi sayfası, yüzlerce sorguyu, satır başına bir sorguyu birleştirme yerine (select_related()) diğer tablodaki verileri almak için yapıyor.Django admin list_select_related bu durumda neden çalışmıyor?

Django docs indicate, ModelAdmin'inize bir özellik olarak list_select_related = True özelliğini ekleyebilir, ancak bunu yapmak benim için hiç işe yaramıyor. This SO question benzer bir sorun veriyor gibi görünüyor, ancak onun çözünürlüğü belirsiz ve benim durumumda işe yaramıyor.

İşte benim modeli ve model yöneticinin bir versiyonudur var: Ancak

class Device(models.Model): 
    serial_number = models.CharField(max_length=80, blank=True, unique=True) 
    label = models.CharField(max_length=80, blank=True) 

    def __str__(self): 
     s = str(self.serial_number) 
     if self.label: 
      s += ': {0}'.format(self.label) 
     return s 

class Event(models.Model): 
    device = models.ForeignKey(Device, null=True) 
    type = models.CharField(max_length=40, null=False, blank=True, default='') 

class EventAdmin(admin.ModelAdmin): 
    list_display = ('__str__', 'device') 
    list_select_related = True 

, list_selected_related = True şey değişmedi belirtti. Hala bu yerine SQL gibi sorgular bir sürü almak katılmak:

Lots of queries, not a join

Herhangi bir fikir Django yönetici benim list_select_related ve yapıyor N sorguları görmezlikten geldiği görülmekte neden? Python 2.7 ve Django 1.3.3 kullanıyorum.

cevap

14

Sorun, list_select_related = True ayarının yalnızca select_related() temel sorguya eklenmesidir, ancak bu çağrı varsayılan olarak null=True ile ForeignKeys öğesini takip etmemektedir. Yani cevap Değişiklik kendini kullanan Sorgu Kümesi tanımlamak ve takip etmek FK belirtmektir:

class EventAdmin(admin.ModelAdmin): 
    list_display = ('__str__', 'device') 
    def queryset(self, request): 
     return super(EventAdmin, self).queryset(request).select_related('device') 
+2

Teşekkür! Yabancı anahtardaki 'null = True', kesinlikle seçili olan şeyin yapılmasını engelliyordu. [Docs] 'u (https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.select_related) takip edersem, Şunu görmüştüm: "Varsayılan olarak, select_related() null = true" –

+0

olan yabancı anahtarları takip etmiyor. İlginizi çekiyor, neden "list_select_related = True" Django için varsayılan değil mi? yönetici? Bu çok daha mantıklı bir varsayılan gibi görünüyor. (Neden varsayılan olarak select_related() 'null = true olan yabancı anahtarları takip etmediğini anlayabiliyorum, çünkü bu bir performans sorunu olabilir, ancak diğer durumlarda 'list_select_related' hakkında merak ediyorum.) –

+0

Django'da> = 1.6 yöntem şimdi 'get_queryset' olarak adlandırıldı. – TAH

6

Since Django 1.6, list_select_relatedselect_related() çağrısına dahil etmek alanların adları ile bir boolean, liste veya tuple kabul eder. Dolayısıyla artık kullanabilirsiniz:

class EventAdmin(admin.ModelAdmin): 
    list_display = ('__str__', 'device') 
    list_select_related = ['device']