Estoy usando ManyToManyField con una clase 'through' y esto da como resultado muchas consultas cuando obtengo una lista de cosas. Me pregunto si hay una manera más eficiente.¿Cómo hago que las consultas Django ManyToMany 'through' sean más eficientes?
Por ejemplo aquí hay algunas clases simplificados para la descripción Libros y sus diversos autores, que pasa por una clase de papel (para definir los roles como "Editor", "ilustrador", etc):
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)
Si llamo Book.authors_names() entonces pueden obtener una cadena como esta:
John Doe (Editor), Fred Bloggs, Billy Bob (Ilustrador)
Funciona bien, pero realiza una consulta para obtener los roles del libro y luego otra consulta para cada persona. Si estoy mostrando una lista de libros, esto se suma a muchas consultas.
¿Hay alguna manera de hacer esto de manera más eficiente, en una sola consulta por libro, con una combinación? ¿O es la única forma de usar algo como batch-select?
(Para los puntos de bonificación ... mi codificación de authors_names() parece un poco torpe - hay una manera de hacerlo más elegante al estilo de Python?)
'Python-esque' es generalmente reservado para las comparaciones con Monty Python: la palabra que está buscando es 'Pythonic'. –
@daniel: +1 para el uso correcto de 'pythonic', aunque el uso de 'python-esque' puede implicar que el autor está tratando de hacer el código un poco más gracioso ... –
Gracias por la corrección. Sin embargo, a partir de ahora me esforzaré por hacer que mi código no solo sea más correcto sino también más divertido. –