2014-07-25 15 views
5

Làm cách nào tôi có thể thực hiện truy vấn mysql này thành django ORM?Truy vấn ORM Django với nhiều trường tham gia

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 

Tôi đã cố gắng

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

nhưng điều này được dịch bằng django như

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

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

này được dịch bằng django như:

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`) 

nếu tôi chạy SQL ở trên trong cơ sở dữ liệu tôi nhận được kết quả đúng ...

Edit: Các mô hình và quan điểm

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> 
+0

Bạn không muốn 'select_related' hoặc' prefetch_related' cho điều này, bạn muốn sử dụng bộ lọc để buộc với mô hình khác, giả sử một khóa ngoại hoặc mối quan hệ nhiều đến nhiều. Bạn có thể đăng mã mô hình của mình không? – Tom

Trả lời

1

Hãy thử truy vấn như thế này:

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') 

Để kiểm tra:

print(qs.query) 

Giải thích:

Từ mô hình sản phẩm của bạn, bạn đang truy cập vào ForeignKey mỗi lần trên avg_price và lĩnh vực liên quan trong mô hình đó mà bạn muốn trở thành NULL mỗi lần khi bạn quay trở lại truy vấn dựa trên LEFT JOIN. Đây là tài liệu về ups nhìn mà span mối quan hệ:

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

Sau đó values_list bạn hãy xác định những giá trị trở lại. Đây là tài liệu về values_list:

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

+0

Tôi đã thử và nhận được lỗi: "FieldError: Không thể giải quyết từ khóa 'avg_price.estimated_price' vào trường". Có vẻ như django không thể nhìn thấy bảng khác ... Ngoài ra tôi sẽ cần phải hiển thị tất cả các kết quả từ các sản phẩm bảng và thêm kết quả từ bảng avg_price bất cứ khi nào có mặt (mach của năm, mô hình và kích thước) ... cảm ơn help – user2950162

+0

Làm thế nào về 'avg_price__estimated_price' thay vì' avg_price.estimated_price'? –

+0

Truy vấn kết quả khác với truy vấn tôi muốn tạo ... 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' IS NULL và 'search_avg_price'.'size' là NULL và' search_avg_price'.' year' IS NULL) – user2950162

1

Bạn có thể vượt qua danh sách bảng để phương pháp thêm() và đặt điều kiện từ ON truy vấn sql của bạn để nơi phần trong thêm()

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"' 
    ] 
) 

đọc thêm về thêm: https://docs.djangoproject.com/en/1.6/ref/models/querysets/#extra

Các vấn đề liên quan