Django model with filterable attributes

I've got two models. One represents a piece of equipment, the other represents a possible attribute the equipment has. Semantically, this might look like:

  • Equipment: tractor, Attributes: wheels, towing
  • Equipment: lawnmower, Attributes: wheels, blades
  • Equipment: hedgetrimmer, Attributes: blades

I want to make queries like,

wheels = Attributes.objects.get(name='wheels')
blades = Attributes.objects.get(name='blades')

Equipment.objects.filter(has_attribute=wheels) \
    .exclude(has_attribute=blades)

How can I create Django models to do this?

This seems simple, but I'm just too dense to see the right solution.

One solution that popped into my head is to encode the list of Attribute IDs in an integer list like |109|14|3 and test for attributes using Equipment.objects.filter(attributes_contains='|%d|' % id) -- but this seems really wrong.

Answers


Your second example is pretty close, but you need to understand how the QuerySet API works across relationships (i.e. joins).

class Attribute(models.Model):
    name = models.CharField(max_length=20)

class Equipment(models.Model):
    name = models.CharField(max_length=20)
    attributes = models.ManyToManyField(Attribute)

equips = Equipment.objects.filter(
    attributes__name='wheels').exclude(attributes__name='blades')

You can use Q objects in your QuerySet to do more interesting queries.

And keep in mind you can always dump the SQL from a QuerySet like this:

print equips.query.as_sql()

Sometimes you'll want to see the exact SQL being generated to make sure you're using the API correctly.


Need Your Help

Detect whenever Boostrap carousel cycles automatically

jquery twitter-bootstrap javascript-events carousel

I am trying to detect whenever the bootstrap carousel is sliding automatically but I can't find anyway of doing so... No info on the slid.bs.carousel that tells if the user triggered the event or i...

How to add an SPI to java sound in an eclipse project?

java audio mp3 javasound

I'm making a media player like java application and I'm using a bunch of different SPIs to provide support for various audio types. I was hoping that adding them would be just as easy as copying them