Gibt es eine einfache Möglichkeit, die ManyToMany-Objekte von einer Abfrage abzurufen, die mehr als ein Objekt zurückgibt? Die Art, wie ich es mache, fühlt sich jetzt nicht so sexy an, wie ich es gerne hätte. Hier ist, wie ich es jetzt meiner Meinung nach mache:ManyToMany-Objekte aus mehreren Objekten über Zwischentabellen holen
contacts = Contact.objects.all()
# Use Custom Manager Method to Fetch Each Contacts Phone Numbers
contacts = PhoneNumber.objects.inject(contacts)
Meine Models:
class PhoneNumber(models.Model):
number = models.CharField()
type = models.CharField()
# My Custom Manager
objects = PhoneNumberManager()
class Contact(models.Model):
name = models.CharField()
numbers = models.ManyToManyField(PhoneNumber, through='ContactPhoneNumbers')
class ContactPhoneNumbers(models.Model):
number = models.ForeignKey(PhoneNumber)
contact = models.ForeignKey(Contact)
ext = models.CharField()
My Custom Manager:
class PhoneNumberManager(models.Manager):
def inject(self, contacts):
contact_ids = ','.join([str(item.id) for item in contacts])
cursor = connection.cursor()
cursor.execute("""
SELECT l.contact_id, l.ext, p.number, p.type
FROM svcontact_contactphonenumbers l, svcontact_phonenumber p
WHERE p.id = l.number_id AND l.contact_id IN(%s)
""" % contact_ids)
result = {}
for row in cursor.fetchall():
id = str(row[0])
if not id in result:
result[id] = []
result[id].append({
'ext': row[1],
'number': row[2],
'type': row[3]
})
for contact in contacts:
id = str(contact.id)
if id in result:
contact.phonenumbers = result[id]
return contacts
Hmm, ich kann das falsch machen. running: cons = Contact.objects.all() [0:50] und dann num = ContactPhoneNumbers.objects.filter (contact__in = cons) führt über 150 Datenbankabfragen aus. – Matt
Ahh hah! contact_phone_numbers = Kontakttelefonnummern. objects.select_related() .filter (contact__in = contacts) Das ist sehr sexy. – Matt
Ich frage mich, ob es schlau genug ist, die Kontakte nicht wieder einzuziehen. Ich werde die Abfrage in Kürze prüfen müssen. – Matt