0

The given below are the models for a retail store.

class Rack(models.Model):
    name = models.CharField(max_length=128)
    number = models.PositiveSmallIntegerField()
    categories = models.ManyToManyField(Category)


class Category(models.Model):
    name = models.CharField(max_length=128)
    code = models.CharField(max_length=3)


class Product(models.Model):
    title = models.CharField(max_length=255)
    in_stock = models.BooleanField(default=False)
    categories = models.ManyToManyField(Category)

Rack : the rack where the products are stocked. Category : the Category of the product. Product : the product

A rack can have multiple categories and same category can be on multiple racks. for ease of managing, I prefer selecting categories on a rack at admin, so prefered this design.

If given a rack, say No.1, How do I query the products on the given rack?

>> Rack.objects.get(number=1).categories.all()

[<Category: Fruits>, <Category: Vegetables>]

I don't want to iterate this query set, but to make a query to return the objects.

my question is, How do I query the objects on a rack as optimized as possible?

so that the query must return a list of objects.

>> Rack.objects.filter( * code here to get the objects in the rack 1 * ) must returns the objects on the rack 1
[<Product: Apple>, <Product: Orange>, <Product: Cucumber>, <Product: Carrot>, <Product: Green Chillie>, <Product: Onion>, <Product: Grapes> ]

Thanks

All Іѕ Vаиітy
  • 24,861
  • 16
  • 87
  • 111

1 Answers1

1

Your best bet might be to use a through model. If you don't want to do that, I'd try out something like this:

categories = Rack.objects.get(number=1).categories.all().values_list('name', flat=True)
Product.objects.filter(categories__name__in=categories)

Also, do you mean for this:

class Product(models.Model):
    ...
    Category = models.ManyToManyField(Category)

to be:

class Product(models.Model):
    ...
    categories = models.ManyToManyField(Category)

like in your Rack model?

Mike Covington
  • 2,147
  • 1
  • 16
  • 26