Performing a Django Query on a Model, But Ending Up with a QuerySet for That Model's ManyToManyField
I have a third party Django App (Satchmo) which has a model called Product
which I make extensive use of in my Django site.
I want to add the ability to search for products via color. So I have created a new model called ProductColor
. This model looks roughly like this...
class ProductColor(models.Model):
products = models.ManyToManyField(Product)
r = models.IntegerField()
g = models.IntegerField()
b = models.IntegerField()
name = models.CharField(max_length=32)
When a store product's data is loaded into the site, the product's color data is used to create a ProductColor
object which will point to that Product
object.The plan is to allow a user to search for a product by searching a color range.
I can't seem to figure out how to put this query into a QuerySet. I can make this...
# If the color ranges look something like this...
r_range, g_range, b_range = ((3,130),(0,255),(0,255))
# Then my query looks like
colors_in_range = ProductColor.objects.select_related('products')
if r_range:
colors_in_range = colors_in_range.filter(
Q(r__gte=r_range[0])
| Q(r__lte=r_range[1])
)
if g_range:
colors_in_range = colors_in_range.filter(
Q(g__gte=g_range[0])
| Q(g__lte=g_range[1])
)
if b_range:
colors_in_range = colors_in_range.filter(
Q(b__gte=b_range[0])
| Q(b__lte=b_range[1])
)
So I end up with a QuerySet which contains all of the ProductColor
objects in that color range. I could then build a list of Product
s开发者_Python百科 by accessing the products
ManyToMany attribute of each ProductColor
attribute.
What I really need is a valid QuerySet of Product
s. This is because there is going to be other logic which is performed on these results and it needs to operate on a QuerySet
object.
So my question is how can I build the QuerySet that I really want? And failing that, is there an efficient way to re-build the QuerySet (preferably without hitting the database again)?
If you want to get a Product
queryset you have to filter the Product
objects and filter via the reverse relation for product color:
products = Product.objects.filter(productcolor_set__r__gte=x).distinct()
You can use the range field lookup:
You can use range anywhere you can use BETWEEN in SQL -- for dates, numbers and even characters.
your query:
r_range, g_range, b_range = ((3,130),(0,255),(0,255))
products = Product.objects.filter(productcolor_set__r__range=r_range,
productcolor_set__g__range=g_range,
productcolor_set__b__range=b_range).distinct()
精彩评论