2011-08-14 42 views
6

Tôi đang viết một lệnh quản lý sẽ lọc giá gốc của sản phẩm với giá được đề xuất.Làm cách nào để so sánh hai trường của mô hình trong truy vấn?

Tôi có một mô hình sản phẩm trông giống như:

class Suggestion(models.Model): 
    .... 
    price = models.IntegerField() 

class Product(models.Model): 
    price = models.IntegerField() 
    suggestions = models.ManyToManyField(Suggestion) 

Tôi muốn lọc tất cả các sản phẩm có giá tương đương với đề nghị minumum. Một cái gì đó nên thích:

Product.objects.filter(price = minumum(suggestions)) 

Tôi muốn lọc sản phẩm mà những gợi ý có giá gốc của sản phẩm. Một cái gì đó nên thích:

Product.objects.filter(price__in = self.suggestions) 

Vấn đề là tôi không thể sử dụng cho vòng lặp để tìm gợi ý minumum của mỗi sản phẩm và như bạn đoán tôi không thể sử dụng đối tượng của tự một trong hai, vậy làm thế nào tôi có thể so sánh hai trường của mô hình trong truy vấn?

Trả lời

8
from django.db.models import F 
Product.objects.filter(price__in=F('suggestions')) 
+1

Cảm ơn! Điều đó hoạt động tốt. Tuy nhiên, có một lỗi nhỏ: các đề xuất phải nằm trong dấu ngoặc kép bên trong F ('đề xuất'). –

2
  • Product.objects.filter(price = minumum(suggestions))

suggestions không phải là một lĩnh vực trên sản phẩm (và các cột truyền cho F nên có dấu ngoặc kép, như F('suggestions') không F(suggestions)). Vì vậy, đó là không tốt.

SQL thô cho điều này giống như thế này, tham gia vào truy vấn con nhận giá tối thiểu cho mỗi sản phẩm, sau đó lọc danh sách xuống các sản phẩm có giá == giá tối thiểu.

SELECT * FROM product 
    LEFT JOIN (
    SELECT _products_suggestions.product_id, MIN(price) as min_price 
    FROM suggestion 
    RIGHT JOIN _products_suggestions 
    GROUP BY _products_suggestions.product_id 
    ) AS min_suggestions ON min_suggestions.product_id = product.id 
    WHERE product.price = min_suggestions.price 

Bạn không thể thực hiện (bằng 1.4) tham gia tùy chỉnh theo cách này bằng cách sử dụng django ORM. Bạn sẽ cần phải sử dụng một số raw SQL query.

  • Product.objects.filter(price__in = self.suggestions)

self.suggestions, giả sử chúng ta trong một phương pháp Product dụ, không phải là một danh sách, cho đến nay nó là một RelatedSetManager. Tuy nhiên, tôi nghi ngờ rằng bạn muốn có được tất cả các sản phẩm có giá được đề xuất là hiện tại (còn gọi là self). Điều đó có vẻ kỳ quặc.

Âm thanh như bạn muốn là danh sách các sản phẩm có đề xuất khớp với một giá được đề xuất.

Bạn sẽ cần SQL thô một lần nữa. : -/

SELECT * FROM product 
    LEFT JOIN _products_suggestions ON _products_suggestions.product_id = product.id 
    LEFT JOIN suggestion ON _products_suggestions.suggestion_id = suggestion.id 
    WHERE suggestion.price = product.price 

Điều đó sẽ làm điều đó, tôi nghĩ vậy. RIGHT JOIN có thể nhanh hơn ở đó, tôi không chắc chắn, nhưng dù sao bạn cũng sẽ có một danh sách các sản phẩm và đề xuất có cùng mức giá.

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