Skip to main content

An extension of django rest framework that allows writing nested relations

Project description


# DRF Nested Relations

This python package is an extension for django rest framework for creating, updating and deleting nested relations. The nested relations can go to `any depth`.

It receives nested data as list of dictionaries.
It works for generic relations and foreign keys for now.


* If the dictionary contains `id` field, the nested data will be updated.

* If the dictionary does not contain `id`, field , new data will be created.

* If the dictionary contains only `id` as key, the data will be deleted.

# Usage

### Models

```python
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType

class ContactData(models.Model):
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, blank=True, null=True)
object_id = models.PositiveIntegerField(blank=True, null=True)
content_object = GenericForeignKey()
phone = models.CharField(max_length=25,blank=True, null=True)
email = models.EmailField()

class Person(models.Model):
name = models.CharField(max_length=50)
contact_data = GenericRelation(ContactData, related_query_name='content_obj_person')

class Skill(models.Model):
name = models.CharField(max_length=50)
person = models.ForeignKey('Person', related_name='skills', on_delete=models.CASCADE)
````

### Serializers

```Python
from rest_framework import serializers
from nested_relations.serializers import NestedDataModelSerializer
from .models import ContactData, Person, Skill

class ContactDataSerializer(serializers.ModelSerializer):
class Meta:
model = ContactData
exclude = ('content_type', 'object_id')

class SkillSerializer(serializers.ModelSerializer):
class Meta:
model = Skill
exclude = ('person',)

class PersonSerializer(NestedDataModelSerializer):

contact_data = serializers.JSONField(required=False, allow_null=True)
skills = serializers.JSONField(required=False, allow_null=True)

class Meta:
model = Person
fields = '__all__'
nestedSerializer = {
'contact_data': {'serializer_class': ContactDataSerializer, 'many': True, 'kwargs': 'content_object'},
'skills':{'serializer_class': SkillSerializer, 'many': True, 'kwargs': 'person'}
}


```


* For generic relation ,
use `field_name = serializers.JSONField()` and same `field_name` in nested serializer. (An attribute in main model that points to nested relation)

* For foreign key,
Use `related_name = serializers.JSONField()` and same `related_name` in nested serializer. (An attribute in main model that points to nested relation)

* For both,
Provide `many=True`. The value for `kwargs` is clear from example. It is an attribute in nested relation that points to main model.

## Writing data
```python
# Creating a person

data = {
"contact_data": [{"email":"1@1.com"},{"email":"2@2.com"}, {"email":"3@3.com"}],
"name": "Sagar"
}

person_serializer = PersonSerializer(data=data, context={'request':request})
person_serializer.is_valid(raise_exception=True)
person = person_serializer.save()
print(person_serializer.data)

{
"id": 3,
"contact_data": [
{
"id": 4,
"phone": null,
"email": "1@1.com"
},
{
"id": 5,
"phone": null,
"email": "2@2.com"
},
{
"id": 6,
"phone": null,
"email": "3@3.com"
}
],
"skills": [],
"name": "Sagar"
}

# Updating the person
data = {
"id": 3,
"contact_data": [
{ # update
"id": 4,
"phone": null,
"email": "1@1edit.com"
},
{ # delete
"id": 5
},
{ # create
"phone": null,
"email": "4@4.com"
}
],
"skills": [],
"name": "Sagar"
}

person_serializer = PersonSerializer(person, data=data, context={'request':request})
person_serializer.save()
print(person_serializer.data)

{
"id": 3,
"contact_data": [
{
"id": 4,
"phone": null,
"email": "1@1edit.com"
},
{ # no change
"id": 6,
"phone": null,
"email": "3@3.com"
},
{
"id": 7,
"phone": null,
"email": "4@4.com"
}
],
"skills": [],
"name": "Sagar"
}
```
## Deeper Relations
For deeper relations, the nested serializer should further inherit `NestedDataModelSerializer` and their corresponding nested serializers have to be provided.




Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

drf-nested-relations-0.0.2.tar.gz (4.9 kB view details)

Uploaded Source

Built Distribution

drf_nested_relations-0.0.2-py3-none-any.whl (8.0 kB view details)

Uploaded Python 3

File details

Details for the file drf-nested-relations-0.0.2.tar.gz.

File metadata

  • Download URL: drf-nested-relations-0.0.2.tar.gz
  • Upload date:
  • Size: 4.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/38.2.4 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.6.3

File hashes

Hashes for drf-nested-relations-0.0.2.tar.gz
Algorithm Hash digest
SHA256 b25d89800101549146a1c447f5bfb576ee6b2875d8594f2a7aa6f09f0fc12ded
MD5 065b9ae4fdba65d84780b45c647f6908
BLAKE2b-256 a6233fcf743ad8d7a56faddeade77e254f864a08b66538b7c9743899f9635fd4

See more details on using hashes here.

File details

Details for the file drf_nested_relations-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: drf_nested_relations-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 8.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/38.2.4 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.6.3

File hashes

Hashes for drf_nested_relations-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 42578e5f11cf8f9ec7c455e34ee1bf6ee7d56c22d13f7dea285e3bfce7506e15
MD5 38e62f92c64b6e40051609e1b2871667
BLAKE2b-256 f0853dcff3d9bfc98273bb43807a32fd6a85884c1abf504a469c0ebec7667979

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page