Skip to content

Latest commit

 

History

History
111 lines (84 loc) · 2.54 KB

README.md

File metadata and controls

111 lines (84 loc) · 2.54 KB

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