Django queryset - Zugabe MIT Einschränkung
Habe ich mit Django für ein paar Jahre jetzt, aber ich bin kämpfen, heute mit dem hinzufügen einer HAVING
Einschränkung einer GROUP BY
.
Meine queryset ist folgende:
crm_models.Contact.objects\
.filter(dealercontact__dealer__pk__in=(265,),
dealercontact__activity='gardening',
date_data_collected__gte=datetime.date(2012,10,1),
date_data_collected__lt=datetime.date(2013,10,1))\
.annotate(nb_rels=Count('dealercontact'))
gibt mir die folgende MySQL-Abfrage:
SELECT *
FROM `contact`
LEFT OUTER JOIN `dealer_contact` ON (`contact`.`id_contact` = `dealer_contact`.`id_contact`)
WHERE (`dealer_contact`.`active` = True
AND `dealer_contact`.`activity` = 'gardening'
AND `contact`.`date_data_collected` >= '2012-10-01'
AND `contact`.`date_data_collected` < '2013-10-01'
AND `dealer_contact`.`id_dealer` IN (265))
GROUP BY `contact`.`id_contact`
ORDER BY NULL;
Ich würde genau das bekommen, was ich brauche mit dieser HAVING
Einschränkung:
HAVING SUM(IF(`dealer_contact`.`type`='customer', 1, 0)) = 0
Wie kann ich diese mit einem festen Django Queryset? Ich brauche ein queryset in diesem Fall.
Hier bin ich mit dem kommentieren nur um die GROUP BY
auf contact.id_contact
.
Bearbeiten: Mein Ziel ist es, die Kontakte, die haben keine "Kunden" - Beziehung in dealercontact haben aber "ref" Beziehung(s) (entsprechend der WHERE-Klausel natürlich).
Modelle
class Contact(models.Model):
id_contact = models.AutoField(primary_key=True)
title = models.CharField(max_length=255L, blank=True, choices=choices_custom_sort(TITLE_CHOICES))
last_name = models.CharField(max_length=255L, blank=True)
first_name = models.CharField(max_length=255L, blank=True)
[...]
date_data_collected = models.DateField(null=True, db_index=True)
class Dealer(models.Model):
id_dealer = models.AutoField(primary_key=True)
address1 = models.CharField(max_length=45L, blank=True)
[...]
class DealerContact(Auditable):
id_dealer_contact = models.AutoField(primary_key=True)
contact = models.ForeignKey(Contact, db_column='id_contact')
dealer = models.ForeignKey(Dealer, db_column='id_dealer')
activity = models.CharField(max_length=32, choices=choices_custom_sort(ACTIVITIES), db_index=True)
type = models.CharField(max_length=32, choices=choices_custom_sort(DEALER_CONTACT_TYPE), db_index=True)
- Ich bin nicht sicher, aber vielleicht .extra() kann nützlich sein, hier docs.djangoproject.com/en/dev/ref/models/querysets/...
- Ich habe versucht, aber die kommentieren + extra gab mir die folgende Fehlermeldung: DatabaseError: (1111, 'Invalid use of group function"). Das Queryset fügt die "SUMME(...)" sowohl in der SELECT-Klausel und die GROUP BY-Klausel, die weired zu mir. Vielleicht kann ich extra ohne das zu kommentieren und zu bewahren noch Holen Sie sich der GRUPPE DURCH?
- Wenn Sie Django-ORM, Sie sollen nicht denken in Bezug auf SQL-Anweisungen. Das ist nicht immer möglich, daher
.extra()
und.raw()
, aber es wäre viel einfacher zu geben, eine gute Antwort auf Ihre Frage, wenn Sie explizit gesättigt den gewünschten Effekt zu erzielen. - Könntest du deine Modelle?
- Gut ich versuche nicht zu denken, im Sinne von SQL, aber ich versuche zu adaptieren, was zu sein scheint eine Schwäche von Django Querysets, aber ich hoffe, ich kann es einfach und dass ich falsch bin. Ich habe die MySQL Abfrage über ein einfaches Django Queryset erst gebaut.Ich bearbeitet meine Frage: Mein Ziel ist es, die Kontakte, die haben keine "Kunden" - Beziehung in dealercontact haben aber "ref" Beziehung(en). Vielen Dank 🙂
- Könnten Sie uns zeigen Ihre Modelle aus?
- Ich bearbeitete die ursprüngliche Nachricht, um meine Modelle. Vielen Dank für die Hilfe Ludwik!!
- Was meinst du mit "ref" Beziehungen?
- Ich meine dealercontact(s) gibt mit type="ref" und dealercontact.id_contact = Kontakt.id_contact.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich dachte, dies aus, indem Sie zwei binäre Felder in
DealerContact
:is_ref
undis_customer
.Wenn
type='ref'
dannis_ref=1
undis_customer=0
.Sonst, wenn
type='customer'
dannis_ref=0
undis_customer=1
.So, ich bin jetzt in der Lage zu verwenden
annotate(nb_customers=Sum('is_customer'))
und verwenden Sie dannfilter(nb_customers=0)
.Den letzten queryset besteht aus:
Tatsächlich gibt es eine Weise können Sie Ihre eigenen benutzerdefinierten
HAVING
undGROUP BY
Klauseln, wenn Sie brauchen.Benutzen Sie einfach mein Beispiel mit Vorsicht - wenn Django ORM-code/Pfade ändern wird in Zukunft Django-Versionen müssen Sie den code zu aktualisieren zu.
Bild, das Sie haben, Buch und Edition Modelle, wo für jedes Buch, das es mehrere Editionen, und Sie möchten, wählen Sie die erste US-Ausgabe von Datum in Buch queryset.
Hinzufügen von benutzerdefinierten
HAVING
undGROUP BY
Klauseln in Django 1.5+:ExtraWhere
enthalten können nicht nur Felder, sondern auch alle raw-sql-Bedingungen und Funktionen zu.Bist du nicht mit raw-query nur weil Sie wollen die orm-Objekt? Mit
Contact.objects.raw()
erzeugen Instanzen ähnlichfilter
. Finden Sie https://docs.djangoproject.com/en/dev/topics/db/sql/ für weitere Hilfe..raw()
sollte der Letzte Ausweg. Es Niederlagen der Zweck des habens ein ORM in den ersten Platz.Diese einfache Abfrage erfüllt diese Anforderung:
Ist das genug, oder brauchen Sie es noch mehr zu tun?
UPDATE: wenn Ihre Forderung
können Sie dies tun: