'Through' sınıfına sahip bir ManyToManyField kullanıyorum ve bu, bir şeyler listesi alırken birçok sorgunun sonucunu veriyor. Daha verimli bir yol var mı diye merak ediyorum. ÖrneğinDjango ManyToMany'i 'sorgular aracılığıyla daha verimli hale getirebilirim?
burada Rol sınıfına geçer Kitap ve onların çeşitli yazarlar açıklayan bazı basitleştirilmiş sınıfları vardır ("Editör", "Illustrator", vb gibi roller tanımlamasını):
class Person(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
@property
def full_name(self):
return ' '.join([self.first_name, self.last_name,])
class Role(models.Model):
name = models.CharField(max_length=50)
person = models.ForeignKey(Person)
book = models.ForeignKey(Book)
class Book(models.Model):
title = models.CharField(max_length=255)
authors = models.ManyToManyField(Person, through='Role')
@property
def authors_names(self):
names = []
for role in self.role_set.all():
person_name = role.person.full_name
if role.name:
person_name += ' (%s)' % (role.name,)
names.append(person_name)
return ', '.join(names)
ben ararsam Book.authors_names() daha sonra böyle bir dize şey elde edebilirsiniz:
John Doe (Editör), Fred Bloggs, Billy Bob (Illustrator)
İyi çalışıyor ama kitap için Rolleri almak için bir sorgu ve ardından her Kişi için başka bir sorgu yapıyor. Kitapların bir listesini görüntülüyorsam, bu bir çok soruyu ekler.
Bunu daha verimli bir şekilde, Kitap başına tek bir sorguda, birleştirme ile yapmanın bir yolu var mı? Veya batch-select gibi bir şeyi kullanmanın tek yolu nedir?
(bonus puan için ... authors_names benim kodlama() biraz aksak görünüyor? - daha zarif Python vari yapmak için bir yol yoktur)
'Python vari' genellikle Monty Python için karşılaştırmalar için ayrılmıştır: Aradığınız kelime 'Pythonic' dir. –
@daniel: 'pythonic' doğru kullanımı için +1, 'python-esque' kullanımının yazarın kodu biraz daha eğlenceli hale getirmek istediğini ima edebilir ... –
Düzeltme için teşekkürler. Ancak, bundan sonra kodumu sadece daha doğru değil aynı zamanda daha eğlenceli hale getirmek için çaba göstereceğim. –