2014-07-25 16 views
5

Wie könnte ich diese mysql-Abfrage in django ORM machen?Django-ORM-Abfrage mit mehreren Join-Feldern

SELECT search_products.model, search_products.year, search_products.size, search_avg_price.estimated_price 
FROM search_products 
left JOIN search_avg_price 
ON search_products.model=search_avg_price.model and search_products.size=search_avg_price.size and search_products.year=search_avg_price.year 

Ich habe bereits versucht,

latest_products = Products.objects.all().prefetch_related("avg_price") 

aber von django als

SELECT `search_products`.`id`, `search_products`.`size`, `search_products`.`year`, , `search_products`.`model`, `search_products`.`avg_price_id` 
FROM `search_products` 

und

latest_products = Products.objects.all().select_related("avg_price") 

Dieser von django übersetzt übersetzt:

SELECT `search_products`.`id`, `search_products`.`size`, `search_products`.`year`, , `search_products`.`model`, `search_products`.`avg_price_id`, `search_avg_price`.`id`, `search_avg_price`.`model`, `search_avg_price`.`size`, `search_avg_price`.`year`, `search_avg_price`.`estimated_price` 
FROM `search_products` 
INNER JOIN `search_avg_price` ON (`search_products`.`avg_price_id` = `search_avg_price`.`id`) 

wenn ich die oben SQL in der Datenbank ausgeführt ich das richtige Ergebnis zu erhalten ...

Edit: Modelle und Ansichten

class Avg_price(models.Model): 
model = models.CharField(max_length=50, blank=True) 
size= models.IntegerField(blank=True, null=True) 
year= models.IntegerField(blank=True, null=True) 
estimated_price= models.IntegerField(blank=True, null=True) 

class Products(models.Model): 
product_id =models.IntegerField(blank=True, null=True) 
link_id = models.CharField(max_length=200, blank=True) 
location = models.CharField(max_length=200, blank=True) 
model = models.CharField(max_length=50, blank=True) 
size= models.IntegerField(blank=True, null=True) 
price= models.IntegerField(blank=True, null=True) 
year= models.IntegerField(blank=True, null=True) 
type=models.ForeignKey(Type) 
avg_price = models.ForeignKey(Avg_price) 

def __unicode__(self): # Python 3: def __str__(self): 
    return self.location 

Vorlage

{% if latest_products %} 
    {% for product in latest_products %} 
    <ul> 
    <li id="col_one"> 
     <h5>{{product.avg_price.estimated_price}}</h5> 
     <h5>{{product.model}}</h5> 
+0

Sie dies nicht tun Möchten Sie 'select_related' oder' prefetch_related' für diesen Zweck verwenden, möchten Sie den Filter verwenden, um eine Bindung mit dem anderen Modell herzustellen, wobei eine Fremdschlüssel- oder Viele-zu-Viele-Beziehung vorausgesetzt wird. Können Sie Ihren Modellcode posten? – Tom

Antwort

1

die Abfrage Versuchen so:

qs = Product.objects.filter(
    avg_price__model__isnull=True).filter(
    avg_price__size__isnull=True).filter(
    avg_price__year__isnull=True).values_list(
    'model', 'year', 'size', 'avg_price__estimated_price') 

zu testen:

print(qs.query) 

Erläuterung:

Von Ihrem Produktmodell, zugreifen Sie die ForeignKey jedes Mal auf avg_price und die relative Feld in diesem Modell, das Sie NULL jedes Mal sein wollen, wenn Sie zurück die Abfrage basiert auf einem LEFT JOIN. Hier ist die Dokumentation auf Look-Ups, die Beziehungen überspannen:

https://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships

Dann values_list lässt Sie angeben, welche Rückgabewerte. Hier ist die Dokumentation auf values_list:

https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.values_list

+0

Ich habe versucht und habe den Fehler: "FieldError: Kann das Schlüsselwort 'avg_price.estimated_price' nicht in das Feld auflösen". Es scheint, dass django den anderen Tisch nicht sehen kann ... Außerdem müsste ich alle Ergebnisse von Tischprodukten anzeigen und das Ergebnis aus der Tabelle avg_price hinzufügen, wenn vorhanden (Mach des Jahres, Modell und Größe) ... danke für die help – user2950162

+0

Wie wäre es mit 'avg_price__estimated_price' anstatt' avg_price.estimated_price'? –

+0

Die resultierende Abfrage unterscheidet sich von der, die ich erstellen möchte ... SELECT 'search_productsmodel',' search_products'.'year', 'search_products'.size',' search_avg_price''estimated_price' FROM 'search_products' INNER JOIN 'search_avg_price' ON (' search_products''avg_price_id' = 'search_avg_price''id) WHERE (' search_avg_price''model' ist NULL und 'search_avg_price''size' ist NULL und' search_avg_price'' Jahr ist NULL) – user2950162

1

Sie Tabellen-Liste Methode übergeben können extra() und stellen Bedingungen von ON Ihrer SQL-Abfrage zu wo Abschnitt in extra()

Product.objects.extra(
    tables=['search_avg_price'], 
    where=[ 
     '"search_products"."model"="search_avg_price"."model"', 
     '"search_products"."size"="search_avg_price"."size"', 
     '"search_products"."year"="search_avg_price"."year"' 
    ] 
) 

lesen Sie mehr Extra: https://docs.djangoproject.com/en/1.6/ref/models/querysets/#extra