2011-08-14 12 views
6

Estoy escribiendo un comando de administración que filtrará el precio original de un producto con los precios sugeridos.¿Cómo puedo comparar dos campos de un modelo en una consulta?

que tienen un modelo de producto que se parece a:

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

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

quiero filtrar todos los productos cuyo precio es igual a la sugerencia estancia mínima. Algo debe gustar:

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

Y

que desea filtrar productos en los que las sugerencias contiene precio original del producto. Algo debe gusta:

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

El problema es que no puedo utilizar un bucle for que mirar sugerencia estancia mínima de cada producto y como supongo que no puedo usar auto del objeto bien, así que ¿cómo se puede comparar lo dos campos de un modelo en una consulta?

Respuesta

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

Gracias! Eso funciona bien Sin embargo, hay un pequeño error: las sugerencias deben estar entre comillas dentro de F ('sugerencias'). –

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

suggestions no es un campo en el producto (y las columnas pasado a F debe tener comillas, como F('suggestions') no F(suggestions)). Entonces eso no está bien.

El SQL en bruto para esto es algo como esto, que se une a una subconsulta que obtiene el precio mínimo para cada producto, luego filtra la lista a aquellos productos cuyo precio == el precio mínimo.

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 

No se puede realizar (a partir de 1.4) una unión personalizada de esta manera utilizando el django ORM. Tendrá que usar un raw SQL query.

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

self.suggestions, suponiendo que estamos en un método Product ejemplo, no es una lista, hasta el momento se trata de un RelatedSetManager. Sin embargo, dudo que desee obtener todos los productos que tienen uno de los precios sugeridos del producto actual (también conocido como self). Eso parece extraño.

Lo que parece que quiere es una lista de productos que tienen una sugerencia que coincida con uno de los precios sugeridos.

Necesitarás SQL sin procesar de nuevo. : -/

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 

Eso lo haría, creo. RIGHT JOIN podría ser más rápido allí, no estoy seguro, pero de todos modos terminaría con una lista de productos y sugerencias que tienen el mismo precio.

Cuestiones relacionadas