Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling different levels of nesting in Django REST Framework

For example, if you take the models:

class Region(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=256)

class Company(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=256)
    region = models.ForeignKey('Region', db_index=True)

class Staff(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=256)
    company = models.ForeignKey('Company', db_index=True)

I know I don't need to include id in these models, but I've done so to make it clearer.

In this example, sometimes you would want to simply return a list of Regions. Other times you'd want to return a list of Regions with a list of each Region's Companies under each Region.

You would also, I imagine, want even more detail where you have a list of Regions, their Company children, and each Company's Staff children.

What's the best way to handle these different levels of depth/detail as far as the rest framework views are concerned. How do people normally deal with this?

By this I mean, what kind of naming conventions would you use when you have say three views returning the same thing at the top level, with the only difference being how many levels of nesting they include?

like image 478
Smills Avatar asked Nov 01 '22 05:11

Smills


1 Answers

To simply return list regions

-->Use simple serializer with many=True while calling it(This will return list of dictionaries)

class SimpleRegionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Region
        fields = ('id', 'name')

For getting list of Regions with a list of each Region's Companies under each Region

-->Use nested serializer

 class CompanySerializer(serializers.ModelSerializer):
     class Meta:
         model = Company
         fields = ('id', 'name')

 class NestedRegionSerializer(serializers.ModelSerializer):
     company = CompanySerializer(many=True, read_only=True)

     class Meta:
         model = Region
         fields = ('id', 'name')

Also change Company model to

 class Company(models.Model):
     id = models.AutoField(primary_key=True)
     name = models.CharField(max_length=256)
     region = models.ForeignKey('Region', db_index=True, related_name='company')

related_name is the same as serializer field in NestedRegionSerializer.

Don't forget to run migrations or syncdb

For more information see http://www.django-rest-framework.org/api-guide/relations/#nested-relationships for more reference.

You can use any level of nesting, If you want you can also specify "depth" as a meta-option which will provide information about depth of nesting.

like image 79
NehaG Avatar answered Nov 14 '22 01:11

NehaG