# 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.
Release files for drf-nested-relations 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| drf-nested-relations-0.0.2.tar.gz | 4.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| drf_nested_relations-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 12.9 kB
Release files / drf-nested-relations-0.0.2.tar.gz
| Download URL | drf-nested-relations-0.0.2.tar.gz |
|---|---|
| Size | 4.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b25d89800101549146a1c447f5bfb576ee6b2875d8594f2a7aa6f09f0fc12ded
|
|
BLAKE2b-256 checksum How to use checksums |
a6233fcf743ad8d7a56faddeade77e254f864a08b66538b7c9743899f9635fd4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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
|
Release files / drf_nested_relations-0.0.2-py3-none-any.whl
| Download URL | drf_nested_relations-0.0.2-py3-none-any.whl |
|---|---|
| Size | 8.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
42578e5f11cf8f9ec7c455e34ee1bf6ee7d56c22d13f7dea285e3bfce7506e15
|
|
BLAKE2b-256 checksum How to use checksums |
f0853dcff3d9bfc98273bb43807a32fd6a85884c1abf504a469c0ebec7667979
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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
|