Metadata-Version: 1.1
Name: drf-nested-relations
Version: 0.0.1
Summary: An extension of django rest framework that allows writing nested relations
Home-page: https://github.com/SagarKAdhikari/drf-nested-relations
Author: Sagar Adhikari
Author-email: ska80117@gmail.com
License: BSD License
Description-Content-Type: UNKNOWN
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.
        
        
        
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: Django :: 2.0 
Classifier: Framework :: Django :: 2.1
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
