开发者

Performing a Django Query on a Model, But Ending Up with a QuerySet for That Model's ManyToManyField

开发者 https://www.devze.com 2023-02-20 04:23 出处:网络
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 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 Products开发者_Python百科 by accessing the products ManyToMany attribute of each ProductColor attribute.

What I really need is a valid QuerySet of Products. 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()
0

精彩评论

暂无评论...
验证码 换一张
取 消