Abdullah Alharbi
Abdullah Alharbi

Reputation: 331

Filtering reverse relationship for a single object in Django

Suppose I have the following two models:

class Person(models.Model):
    """
    A person model with the name of the person.
    """
    name = models.CharField()


class Vehicle(models.Model):
    """
    A vehicle model with the owner of the vehicle, and the type of the vehicle.
    A vehicle type could be a car, a truck or a bike.
    """
    owner = Models.ForeignKey(Person, related_name='vehicles')
    type = models.CharField()

With these two models, Django will automatically create a backwards relation where all vehicles of a person could be accessed by the following query:

    person = Person.objects.get(pk=1)
    person.vehicles.all()

This will return all vehicles related to that person, so far so good.

Now suppose that I want to get the person object with the vehicles filtered, say I want only vehicles of a bike type. How could I do that?

To put the question in a context, I'm trying to build the following urls:

    api.example.com/v1/person/1/vehicles/ [returns all vehicles]
    api.example.com/v1/person/1/vehicles/?type=bike [returns only vehicles of type bike]

Thank you.

Upvotes: 5

Views: 6773

Answers (1)

Shang Wang
Shang Wang

Reputation: 25539

person.vehicles.filter(type='Bike')

BTW, It's not that good to use type as field name, because it's a python reserved keyword. Try to make it vehicle_type instead.

Edit:

If you want person objects, do:

Person.objects.filter(vehicles__type="Bike")

Check django doc about chaining filters.

ReEdit:

To get a single person's owned bikes, you do:

person = Person.objects.get(pk=1)
all_bikes = person.vehicles.filter(type="Bike")

Upvotes: 12

Related Questions