How could I make this mysql query into django ORM?
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
I have already tried
latest_products = Products.objects.all().prefetch_related("avg_price")
but this is translated by django as
SELECT `search_products`.`id`, `search_products`.`size`, `search_products`.`year`, , `search_products`.`model`, `search_products`.`avg_price_id`
FROM `search_products`
and
latest_products = Products.objects.all().select_related("avg_price")
This is translated by django as:
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` )
if I run the above SQL in the database I get the proper result...
Edit: Models and views
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
Template
{% if latest_products %}
{% for product in latest_products %}
<ul>
<li id="col_one">
<h5>{{product.avg_price.estimated_price}}</h5>
<h5>{{product.model}}</h5>
You can pass tables list to method extra() and put conditions from ON of your sql query to where section 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"'
]
)
read more about extra: https://docs.djangoproject.com/en/1.6/ref/models/querysets/#extra
Try the query like this:
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')
To test:
print(qs.query)
Explanation:
From your Product model, you are accessing the ForeignKey
each time on avg_price
and the relative field in that model that you want to be NULL
each time when you return the query based on a LEFT JOIN
. Here's the documentation on look ups that span relationships:
https://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships
Then values_list
let's you specify which values to return. Here's the documentation on values_list:
https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.values_list
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With