Как я могу сравнить два поля модели в запросе? - PullRequest
7 голосов
/ 14 августа 2011

Я пишу команду управления, которая отфильтрует первоначальную цену продукта с предлагаемыми ценами.

У меня есть модель продукта, которая выглядит следующим образом:

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

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

Я хочу отфильтровать все продукты, цена которых равна минимальному предложению.Что-то должно понравиться:

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

И

Я хочу отфильтровать товары, где предложения содержат первоначальную цену товара.Что-то должно выглядеть так:

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

Проблема в том, что я не могу использовать цикл for для просмотра минимального предложения каждого продукта, и, как вы догадываетесь, я тоже не могу использовать self объектатак как я могу сравнить два поля модели в запросе?

Ответы [ 2 ]

10 голосов
/ 14 августа 2011
from django.db.models import F
Product.objects.filter(price__in=F('suggestions'))
2 голосов
/ 15 июня 2012
  • Product.objects.filter(price = minumum(suggestions))

suggestions не является полем в Product (и столбцы, переданные в F должны иметь кавычки, например F('suggestions'), а не F(suggestions)).Так что это нехорошо.

Необработанный SQL для этого - что-то вроде этого, который присоединяется к подзапросу, который получает минимальную цену для каждого продукта, а затем фильтрует список до тех продуктов, цена которых == минимальная цена.

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

Вы не можете выполнить (начиная с 1.4) пользовательское объединение таким образом, используя django ORM.Вам нужно будет использовать необработанный SQL-запрос .

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

self.suggestions, предполагая, что мы в Product метод экземпляра, это не список, пока это RelatedSetManager.Я сомневаюсь, однако, что вы хотите получить все продукты, которые имеют одну из рекомендованных цен на текущий (он же self) продукт.Это кажется странным.

То, что вам нужно, это список продуктов, предложение которых соответствует одному из предложенных цен.

Вам понадобится сырьеСнова SQL: - /

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

Думаю, так и будет.RIGHT JOIN там может быть быстрее, я не уверен, но в любом случае вы получите список продуктов и предложений, которые имеют ту же цену.

...