2016-05-05 9 views
0

Ist es möglich, eine zusätzliche Raw-SQL-Klausel zu einem Django-Queryset hinzuzufügen? Vorzugsweise mit der RawSQL-Klausel zu einem normalen Abfrage-Set. Es sollte ein normales Abfrage-Set und kein Rawqueryset sein, weil ich es im Django-Admin verwenden möchte.Raw-SQL-Where-Klausel zu Django-Queryset hinzufügen

In meinem speziellen Fall möchte ich eine additonal exists where-Klausel hinzuzufügen:

and exists (
    select 1 
    from ... 
) 

In meinem konkreten Fall habe ich zwei Modelle Customer und Subscription. Die Subscription hat ein start und optional end Datumsfeld.

Ich möchte eine Abfrage mit allen Kunden haben, die heute ein Abonnement haben. Wie diese SQL-Abfrage:

select * 
from customers_customer c 
where exists (
    select 1 
    from subscriptions_subscription sc 
    where sc.customer_id = c.id 
    and sc.start < current_date 
    and (sc.end is null or sc.end > current_date) 
) 

war ich nicht in der Lage eine queryset aus diesem zu machen. Das Beste, was ich ankam, war so etwas wie:

cs = Customer.objects.annotate(num_subscriptions=RawSQL(
     ''' 
     select count(sc.id) 
     from subscriptions_customersubscription sc 
     where sc.customer_id = customers_customer.id 
     and sc.start < current_date 
     and (sc.end is null or sc.end > current_date) 
     ''', [] 
    )) 

Aber diese Abfrage nicht durchführt, sowie die SQL-Abfrage mit den where exists.

+1

Können Sie Ihre Modelle veröffentlichen? Sie versuchen, Tabellen manuell zu verbinden, gab es da ein Problem, wie 'Customer.objects.filter (subscriptions__start__lt = current_date)' etc? – serg

+0

OK der natürliche Join funktioniert und macht genau das, was ich haben möchte ... Ich habe einfach nicht daran gedacht ... – DanEEStar

Antwort

2

Nicht Ihre Frage zu beantworten, aber Sie können die Kunden wie folgt abfragen:

from django.db.models import Q 

Customer.objects.filter(
    Q(subscription__start__lt=current_date), 
    Q(subscription__end=None) | Q (subscription__end__gt=current_date) 
).distinct() 
+0

Nun, ich habe nicht an die einfache Lösung gedacht. Obwohl dies die Frage nicht beantwortet, löst es mein Problem so: upvote – DanEEStar