Serialization

Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON, XML or other content types.

Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.

# Serialize data at
* create
* update
* get - retrievel of a models
  • Files
# Create
snippets/serializers.py

# Update
snippets/views.py
snippets/urls.py

Serializer

  • Gives you a powerful, generic way to control the output of your responses
  • View CODE here
class SnippetsSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    title = serializers.CharField(required=False, allow_blank=True, max_length=10)
    # Add all the fieds that you want to Display/Serialize

    ...
    def create(self, validated_data):
        return Snippet.objects.create(**validated_data)

    def update(self, instance, validated_data):
        ...
        instance.title = validated_data.get('title', instance.title)
        instance.save()
        return instance

ModelSerializer

  • It provides shortcut for creating serializers.
  • SnippetSerializer-class is replicating a lot of information that’s also contained in the Snippet-model.
  • It would be nice if we could keep our code a bit more concise
  • View CODE here
# SnippetSerializer-class  --> ModelSerializer class
class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Snippet
        # Add only those fields which you want to display
        fields = ['id', 'title', 'code', 'linenos', 'language', 'style']
  • To add all fields
    • fields = '__all__'

views.py

@csrf_exempt
def snippet_list(request):    
    if request.method == 'GET':
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        return JsonResponse(serializer.data, safe=False)

    elif request.method == 'POST':
        data = JSONParser().parse(request)
        serializer = SnippetSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data, status=201)  
        return JsonResponse(serializer.errors, status=400)
  • @csrf_exempt
    • This decorator marks a view as being exempt from the protection ensured by the middleware
    • Normally should not do this –> for POST, PUT and DELETE operations
  • many = True
    • Use this to serialize a queryset or list of objects instead of a single object instance use many=True
  • safe=False
    • Use this to serialized non-dict obj
    • By defaults safe=True –> to serialized Dict obj
  • JsonResponse
    • serialized to JSON
  • JSONParser().parse(request)
    • Parse POST data to JSON
  • Status
    • 201 —> successfully created an object
    • 400 —> Bad request
@csrf_exempt
def snippet_detail(request, pk):    
    try:
        snippet = Snippet.objects.get(pk=pk)
    except Snippet.DoesNotExist:
        return JsonResponse({"error": "question not found "}, status=404)

    if request.method == 'GET':
        serializer = SnippetSerializer(snippet)
        return JsonResponse(serializer.data)

    elif request.method == 'PUT':
        data = JSONParser().parse(request)
        serializer = SnippetSerializer(snippet, data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data, status=200)
        return JsonResponse(serializer.errors, status=400)

    elif request.method == 'DELETE':
        snippet.delete()
        return JsonResponse({"Success": "question deleted "}, status=204)

urls.py

urlpatterns = [
    path('snippets/', views.snippet_list),
    path('snippets/<int:pk>/', views.snippet_detail),
]

customize the serialization behavior

https://testdriven.io/blog/drf-serializers/

Two of the most useful functions inside the BaseSerializer class that we can override are to_representation() and to_internal_value(). By overriding them, we can change the serialization and deserialization behavior, respectively, to append additional data, extract data, and handle relationships.

  • to_representation() allows us to change the serialization output
  • to_internal_value() allows us to change the deserialization output

NOTE

  • ‘rest_framework’, not added in installed app
    • Works with POSTMAN
    • Error in browser: rest_framework/api.html
      • For this need to add

Reference