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.decorators import helper_data_add, helper_data_update_with_delete
from nested_relations.serializers import NestedDataSerializer
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(NestedDataSerializer, serializers.ModelSerializer):

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},
'skills':{'serializer_class': SkillSerializer, 'many': True, 'type': 'fk', 'kwargs': 'person'}
}

@helper_data_add
def create(self, validated_data):
return super().create(validated_data)

@helper_data_update_with_delete
def update(self, instance, validated_data):
return super().update(instance, validated_data)
```


* For generic relation ,
use `field_name = serializers.JSONField()` and same `field_name` in nested serializer. No need to provide anything extra in nested serializer. By default, it assumes `content_object` in the models.

* For foreign key,
Use `related_name = serializers.JSONField()` and same `related_name` in nested serializer.
Provide type `fk` and provide `field_name` as kwargs.

## 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(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 `NestedDataSerializer`, the same decorators have to be applied to create and update methods, 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.1.tar.gz (5.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

drf_nested_relations-0.0.1-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: drf-nested-relations-0.0.1.tar.gz
  • Upload date:
  • Size: 5.0 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.1.tar.gz
Algorithm Hash digest
SHA256 ff17f236cc815ffa8886cbbe5e3507487ae14e2f854bb59c5dee7d401312d9b0
MD5 997b44d77e6b8be87903869ab4fe3433
BLAKE2b-256 7c9b6eabdf3f9da9d653939e55a885811855ba5b85276ac6377e6af63a51e85d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: drf_nested_relations-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 8.1 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4e977dabd3b90764a36c86e0fcce9e4c36b59168cb3c1ac314474061d15e2087
MD5 f1d10d946eb3aef715c39c0dc18399c5
BLAKE2b-256 d508bddddb980a74b3558cd5b93bdfd34a27f81e5006676a13da2b71291e3c60

See more details on using hashes here.

Supported by

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