2011-06-17 13 views
6

Ben video arasında birçok ilişki bir biri ile çok basit bir datamodel var ve (bütün yorumlarla videoları) videolar için sorgulamak ve tüm nesne grafiğini kapmak isteyenDjango'da n + 1 seçim nasıl engellenir?

class Video(models.Model): 
    url = models.URLField(unique=True) 
    ..... 

class Comment(models.Model): 
    title = models.CharField(max_length=128) 
    video = models.ForeignKey('Video') 
     ..... 

yorumlar. Sql'ye baktığımda iki tane seçtiğini görüyorum, biri Videolar için ve Yorumlar için bir tane. Bunu nasıl önleyebilirim? Katılmak ve hemen her şeyi almak istiyorum.

Bunu django ile yapmak mümkün mü?

cevap

0

select related'un beklediğiniz gibi çalıştığını görürseniz, bunun için yapıldı.

10

ForeignKey için, selected_related() kullanabilirsiniz:

Comment.objects.select_related('video').all() 

Size yanı sıra videolar için coments toplama, yalnızca bir sorgu oluşturur.

Daha karmaşık bir şey için (M2M gibi), optimizasyon yapmak için unjoinify gibi harici bir uygulamaya ihtiyacınız vardır, ancak bunları daha sonra nesnelerin içine koymak için SQL sorgularını kullanır.

  • django-batch-select değil tam bir çözüm, ancak yardımcı olur:

    • django-queryset-transform: Bu (ben) ile unconfortable ise

      , bazı alternatifler var roughtly M2M ve ile çalışan bir select_related ilişkilerini ters .

  • +0

    Tersini yapmak, videodan yorumlar almak istiyorum. Videolar için sorgulamak istiyorum ancak bu videolar için tüm yorumları alın ve şöyle bir sql ifadesine sahip olursunuz: video v select v.id = c.video_id burada v.date> some_date. Fikir, tüm videoları ve yorumlarını bir sorguda elde etmektir. – bvk

    +0

    Üzgünüz, benim sql ifademde üretmek doğru değildi. Aşağıdakileri oluşturmak istiyorum: Videolardan soldan * seçin v join v.id = c.id burada v.date> some_date. Aslında tüm videoları ve yorumlarını, yorumları olmayan videoları bile istiyorum. Bu örnek _Comment.objects.filter (video__title__starts_with = 'The') .select_related ('video'). All() _ yorumsuz videolar almayacaktır. – bvk

    +0

    Bu yüzden size bunu sizin için yapabilecek django-batch-select gibi diğer araçlara bir link verdim: "rotamly M2M ve TERS İLİŞKİLERİ ile çalışan bir select_related". –

    1

    Yapmanız gereken şey Yorum'da select_related özelliğini kullanmaktır.

    '' ve bunun

    comments = Comment.objects.filter(video__title__starts_with='The') 
          .select_related('video').all() 
    

    Bu tüm yorumlar ve bu yoruma uygun video nesnesini yükleyecektir ilgili yorumlarla başlar kimin başlık Tüm videoları bulmalıyız düşünelim. Videoların üzerinde yinelemek için Videonun üzerinde dönmeniz gerekecektir. Hafızada döndürme yapmak için python itertools.groupby işlevini kullanın.

    İlgili konular