Working with the Django shell and diving deeply into serialization and deserialization

We can launch our default Python interactive shell in our virtual environment and make all the Django project modules available before it starts. This way, we can check that the serializer works as expected. We will do this to understand how serialization works in Django.

Run the following command to launch the interactive shell. Make sure you are within the restful01 folder in the terminal, Command Prompt, or Windows Powershell:

python manage.py shell

You will notice a line that says (InteractiveConsole) is displayed after the usual lines that introduce your default Python interactive shell. The following screenshot shows the Django shell launched in a Windows command prompt:

Enter the following code in the Python interactive shell to import all the things we will need to test the Toy model and its serializer. The code file for the sample is included in the hillar_django_restful_02_01 folder, in the restful01/toy_serializers_test_01.py file:

from datetime import datetime 
from django.utils import timezone 
from django.utils.six import BytesIO 
from rest_framework.renderers import JSONRenderer 
from rest_framework.parsers import JSONParser 
from toys.models import Toy 
from toys.serializers import ToySerializer 

Enter the following code to create two instances of the Toy model and save them. The code file for the sample is included in the hillar_django_restful_02_01 folder, in the restful01/toy_serializers_test_01.py file:

toy_release_date = timezone.make_aware(datetime.now(), timezone.get_current_timezone()) 
toy1 = Toy(name='Snoopy talking action figure', description='Snoopy speaks five languages', release_date=toy_release_date, toy_category='Action figures', was_included_in_home=False) 
toy1.save() 
toy2 = Toy(name='Hawaiian Barbie', description='Barbie loves Hawaii', release_date=toy_release_date, toy_category='Dolls', was_included_in_home=True) 
toy2.save() 

After we execute the preceding code, we can check the SQLite database with the previously introduced command-line or GUI tools to check the contents of the toys_toy table. We will notice the table has two rows and columns with the values we have provided to the different attributes of the Toy instances. The following screenshot shows the results of browsing the data of the toys_toy table with the DB Browser for SQLite GUI utility. We can see that two rows were inserted.

Enter the following code in the interactive shell to check the values for the primary keys or identifiers for the saved Toy instances, and the value of their name and was_included_in_home_attribute attributes. The code also checks the value of the created attribute, which includes the date and time at which Django saved each instance to the database. The code file for the sample is included in the hillar_django_restful_02_01 folder, in the restful01/toy_serializers_test_01.py file:

print(toy1.pk) 
print(toy1.name) 
print(toy1.created) 
print(toy1.was_included_in_home) 
print(toy2.pk) 
print(toy2.name) 
print(toy2.created) 
print(toy2.was_included_in_home)

The following screenshot shows sample results of the previously shown code:

Now, let's write the following code to serialize the first Toy instance (toy1). The code file for the sample is included in the hillar_django_restful_02_01 folder, in the restful01/toy_serializers_test_01.py file:

serializer_for_toy1 = ToySerializer(toy1) 
print(serializer_for_toy1.data) 

The following lines show the generated dictionary, specifically, a rest_framework.utils.serializer_helpers.ReturnDict instance, stored in the serializer_for_toy1.data attribute. The next lines show the results with easily understood formatting:

    {
        'pk': 1, 
        'name': 'Snoopy talking action figure', 
        'description': 'Snoopy speaks five languages', 
        'release_date': '2017-10-09T12:11:37.090335Z', 
        'toy_category': 'Action figures', 
        'was_included_in_home': False
    }

Now, let's serialize the second Toy instance (toy2). The code file for the sample is included in the hillar_django_restful_02_01 folder, in the restful01/toy_serializers_test_01.py file:

serializer_for_toy2 = ToySerializer(toy2) 
print(serializer_for_toy2.data)

The following lines show the generated dictionary stored in the serializer_for_toy2.data attribute. The next lines show the results with easily understood formatting:

    {
        'pk': 2, 
        'name': 'Hawaiian Barbie', 
        'description': 'Barbie loves Hawaii', 
        'release_date': '2017-10-09T12:11:37.090335Z', 
        'toy_category': 'Dolls', 
        'was_included_in_home': True
    }  

We can easily render the dictionaries held in the data attribute into JSON with the help of the rest_framework.renderers.JSONRenderer class. The following lines create an instance of this class and then call the render method to render the dictionaries held in the data attribute into JSON. The code file for the sample is included in the hillar_django_restful_02_01 folder, in the restful01/toy_serializers_test_01.py file:

json_renderer = JSONRenderer() 
toy1_rendered_into_json = json_renderer.render(serializer_for_toy1.data) 
toy2_rendered_into_json = json_renderer.render(serializer_for_toy2.data) 
print(toy1_rendered_into_json) 
print(toy2_rendered_into_json) 

The following lines show the output generated from the two calls to the render method:

    b'{"pk":1,"name":"Snoopy talking action figure","description":"Snoopy speaks five languages","release_date":"2017-10-09T12:11:37.090335Z","toy_category":"Action figures","was_included_in_home":false}'
    >>> print(toy2_rendered_into_json)
    b'{"pk":2,"name":"Hawaiian Barbie","description":"Barbie loves Hawaii","release_date":"2017-10-09T12:11:37.090335Z","toy_category":"Dolls","was_included_in_home":true}'  

Now, we will work in the opposite direction: from serialized data to the population of a Toy instance. The following lines generate a new Toy instance from a JSON string (serialized data), that is, the code deserializes and parses the data. The code file for the sample is included in the hillar_django_restful_02_01 folder, in the restful01/toy_serializers_test_01.py file:

json_string_for_new_toy = '{"name":"Clash Royale play set","description":"6 figures from Clash Royale", "release_date":"2017-10-09T12:10:00.776594Z","toy_category":"Playset","was_included_in_home":false}' 
json_bytes_for_new_toy = bytes(json_string_for_new_toy, encoding="UTF-8") 
stream_for_new_toy = BytesIO(json_bytes_for_new_toy) 
parser = JSONParser() 
parsed_new_toy = parser.parse(stream_for_new_toy) 
print(parsed_new_toy) 

The first line creates a new string with the JSON that defines a new toy (json_string_for_new_toy). The next line converts the string to bytes and saves the results of the conversion in the json_bytes_for_new_toy variable. The django.utils.six.BytesIO class provides a buffered I/O implementation using an in-memory bytes buffer. The code uses this class to create a stream from the previously generated JSON bytes with the serialized data, json_bytes_for_new_toy, and saves the generated stream instance in the stream_for_new_toy variable.

We can easily deserialize and parse a stream into a Python model with the help of the rest_framework.parsers.JSONParser class. The next line creates an instance of this class and then calls the parse method with stream_for_new_toy as an argument, parses the stream into Python native datatypes, and saves the results in the parsed_new_toy variable.

After executing the previous lines, parsed_new_toy holds a Python dictionary, parsed from the stream. The following lines show the output generated after executing the preceding code snippet. The next lines show the results with easily understood formatting:

       {
    
    
          'name': 'Clash Royale play set', 
    
    
          'description': '6 figures from Clash Royale', 
    
    
          'release_date': '2017-10-09T12:10:00.776594Z', 
    
    
          'toy_category': 'Playset', 
    
    
          'was_included_in_home': False
    
    
      } 

The following lines use the ToySerializer class to generate a fully populated Toy instance named toy3 from the Python dictionary, parsed from the stream. The code file for the sample is included in the hillar_django_restful_02_01 folder, in the restful01/toy_serializers_test_01.py file:

new_toy_serializer = ToySerializer(data=parsed_new_toy) 
if new_toy_serializer.is_valid(): 
    toy3 = new_toy_serializer.save() 
    print(toy3.name)

First, the code creates an instance of the ToySerializer class with the Python dictionary that we previously parsed from the stream (parsed_new_toy) passed as the data keyword argument. Then, the code calls the is_valid method to check whether the data is valid.

Note that we must always call is_valid before we attempt to access the serialized data representation when we pass a data keyword argument in the creation of a serializer.

If the method returns true, we can access the serialized representation in the data attribute, and therefore, the code calls the save method that persists the new instance. In this case, it is a new Toy instance, and therefore the code to the save method inserts the corresponding row in the database and returns a fully populated Toy instance, saved in the toy3 local variable. Then, the code prints one of the attributes from the fully populated Toy instance. After executing the previous code, we fully populated a new Toy instance: toy3.

As we can see from the previous code, Django REST framework makes it easy to serialize from objects to JSON and deserialize from JSON to objects, which are core requirements for our RESTful Web Service that has to perform CRUD operations.

Enter the following command to leave the Django shell with the Django project modules that we loaded to test serialization and deserialization:

quit() 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.47.221