Skip to content

stschindler/djangorestframework-deep

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DRF Deep

DRF Deep makes using embedded resources in DRF as easy as pie.

What Deep does that DRF doesn't do

With Django REST Framework alone, you can only read embedded resources from the API, like this order:

{
  "id": 2,
  "customer": "Tom Christie",
  "items": [
    {"id": 1, "name": "Pizza Salami", "quantity": 3},
    {"id": 2, "name": "Pizza Funghi", "quantity": 1},
  ]
}

However, as soon as you plan to write back such data, DRF tells you that it can't do it. The reason given by the author, Tom Christie, is that there are multiple strategies on how to interpret such requests.

While he's right, there's one strategy that works just great. See the following PUT example requests that demonstrate the behavior.

Scenario 1: Create new embedded resources

{
  "items": [
    {"name": "Pizza Salami", "quantity": 3},
    {"name": "Pizza Funghi", "quantity": 1},
  ]
}

Because the embedded item resources do not contain an id field, DRF Deep assumes that the caller wants to create new resources.

Scenario 2: Update embedded resources

{
  "items": [
    {"id": 1, "name": "Pizza Salami", "quantity": 3},
    {"id": 2, "name": "Pizza Funghi", "quantity": 1},
  ]
}

Now the embedded items both contain id fields, meaning DRF Deep will fetch the existing items from the database and update them accordingly.

Scenario 3: Deleting embedded resources

{
  "items": [
    {"id": 2, "name": "Pizza Funghi", "quantity": 1},
  ]
}

The item with the ID of 2 will be updated, like explained before. However the pizza #1 is missing from the request, so DRF Deep will also drop it from the database.

Scenario 4: Not touching embedded resources

{
  "customer": "Stefan Schindler"
}

As no items field is present, DRF Deep will do nothing with the items of this order. Instead only the customer data is updated.

Quickstart

pip install djangorestframework-deep

In your serializers.py:

from rest_framework.serializers import ModelSerializer
from rest_framework_deep.mixins import EmbeddedMixin

class ItemSerializer(ModelSerializer):
  class Meta:
    model = Item
    fields = ("id", "name", "quantity")

class OrderSerializer(EmbeddedMixin, ModelSerializer):
  class Meta:
    model = Order
    fields = ("id", "customer", "items")
    embedded_fields = {"items": ItemSerializer}

That's it!

Contact

About

Use DRF with embedded resources, both for reading and writing

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages