Search code examples
pythondjangotastypie

Django Tastypie: Filtering by ForeignKey


I would like Django Tastypie to return a query filtered by a ForeignKey. Here are my two models:

class Origin(models.Model):
    country = models.CharField(max_length=1024)

class Fruits(models.Model):
    origin      = models.ForeignKey(Origin)
    fruit_name  = models.CharField(max_length=1024)
    is_sweet    = models.BooleanField()
    quantity    = models.IntegerField()

Based on the documentation here, I'm using the following resources.py:

class FruitResource(ModelResource):
    class Meta:
        queryset = Fruits.objects.all()
        allowed_methods = ['get']      
        filtering = {
            "origin": ('exact',)
            }

This is the URL I'm trying to access:

http://localhost:8000/api/v1/fruit/?format=json&origin__country=Nepal

Accessing that URL returns the following output:

{
  "meta": 
    {
      "limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 2}, "objects": 
        [
          {"fruit_name": "Apple", "id": 1, "is_sweet": true, "quantity": 10, "resource_uri": "/api/v1/fruit/1/"}, 
          {"fruit_name": "Banana", "id": 2, "is_sweet": true, "quantity": 10, "resource_uri": "/api/v1/fruit/2/"}
        ]
}

I should mention that I get the same output using this URL:

http://localhost:8000/api/v1/fruit/?format=json

What is the correct way to get a list of Fruits objects by specifying the country attribute of the Origin?


Solution

  • I was able to get it working based on this answer. I'm listing the final code here for the benefit of others.

    from tastypie.resources import ModelResource, fields, ALL_WITH_RELATIONS
    
    from fruits.models import Fruits
    from origin.models import Origin
    
    class OriginResource(ModelResource):
        class Meta:
            queryset = Origin.objects.all()
            resource_name = 'origin'
            filtering = {
                "country": ('exact',)
                }
    
    class FruitResource(ModelResource):
        origin = fields.ForeignKey(OriginResource, 'origin', full=True)
        class Meta:
            queryset = Fruits.objects.all()
            allowed_methods = ['get']
            filtering = {
                "origin": ALL_WITH_RELATIONS,
                }
    

    With this code, if I hit http://localhost:8000/api/v1/fruit/?format=json&origin__country=Nepal , I get the following expected output:

    {"meta": 
      {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 1},
       "objects": [{
             "fruit_name": "Apple", "id": 1, "is_sweet": true, "origin":
             {"country": "Nepal", "id": 3, "resource_uri": ""},
             "quantity": 10, "resource_uri": "/api/v1/fruit/1/"
        }]
    }