brief introduction
DRF (Django REST framework) is a powerful and flexible toolkit for building RESTful web APIs. It is a secondary development based on Django framework. It is called DRF framework or REST framework for short.
characteristic
- It provides a powerful Serializer serializer, which can serialize and deserialize efficiently
- It provides extremely rich class views, Mixin extension classes and ViewSet view sets
- Provides an intuitive Web API interface
- Multiple identity authentication and authority authentication
- Powerful sorting, filtering, paging, search, flow limiting and other functions
- Extensibility and rich plug-ins
install
pip install djangorestframework
Set rest_ Add framework to installed_ In apps settings:
INSTALLED_APPS = [ 'rest_framework', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
Basic use of serializers
Serializer - serializer
The biggest feature of the drf framework is its serializer. Its functions are as follows:
- Serialize the model object into a dictionary and provide it to the view in the future. After the response, it becomes a json string.
- The data sent by the client is called request through the view to become a python dictionary, and the serializer can convert the dictionary into a model.
- Complete the function of database checksum operation
Define serializer
Continue to use the student table you created earlier to demonstrate the basic use of the serializer
from django.db import models class Student(models.Model): """ Student list """ name = models.CharField('Student name', max_length=200, unique=True, help_text='Student name') gender = models.SmallIntegerField('Gender', default='1', help_text='Gender') hobby = models.CharField('hobby', max_length=200, null=True, blank=True, help_text='hobby') age = models.IntegerField('Age', null=True, ) create_time = models.DateTimeField('Creation time', auto_now_add=True, help_text='Creation time') grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True, related_name='students') # Set foreign keys, cascade delete) class Meta: """ Metadata, """ db_table = 'student' # Specifies that the current model created by the current model does not write the default current model name Student verbose_name = 'Student information sheet' # notes verbose_name_plural = verbose_name # Specify as plural
Create the serializers.py file in the application directory, define classes and inherit rest_framework.serializers.Serializer is similar to the model. This serializer is defined to serialize project objects, so the fields correspond to the fields in the model one by one.
from rest_framework import serializers class ProjectSerializer(serializers.Serializer): """ Project serializer """ id = serializers.IntegerField(label='student id', read_only=True) # read-only name = serializers.CharField(label='Student name') hobby = serializers.CharField(label='hobby',allow_null=True,required=False) # allow_null allows receiving null,required=False. This field can be ignored when instantiating an object age = serializers.IntegerField(label='Age') c_time = serializers.DateTimeField(label='Creation time', read_only=True)
Use serializer
1, Serialize model instances
In [12]: from projects.models import * In [13]: from projects.serializers import ProjectSerializer In [14]: s=Student.objects.first() # Instantiate an object In [15]: p = ProjectSerializers(s) # Convert to dictionary by serializer In [16]: p.data Out[17]: {'id': 3, 'name': 'test3', 'hobby': 'play a game', 'age': 19}
In order to complete the serialization process and convert it to json, you need to import
Out[17]: from rest_framework.renderers import JSONRenderer In [18]: JSONRenderer().render(p.data) Out[18]: b'{"id":3,"name":"test3","hobby":"\xe7\x8e\xa9\xe6\xb8\xb8\xe6\x88\x8f","age":19}'
2, Serialize query set
Specify that the many parameter is equal to True when using the serializer
In [22]: s1 = Student.objects.all() In [23]: p1 = ProjectSerializers(s1) In [25]: p1.data In [26]: p1 = ProjectSerializers(s1,many=True) In [27]: p1.data Out[27]: [OrderedDict([('id', 3), ('name', 'test3'), ('hobby', 'play a game'), ('age', 19)]), OrderedDict([('id', 4), ('name', 'Zhang San'), ('hobby', 'play'), ('age', 21)]), OrderedDict([('id', 5), ('name', 'zhaom'), ('hobby', 'play'), ('age', 112)]), OrderedDict([('id', 8), ('name', 'Ah San'), ('hobby', 'play'), ('age', 22)]), OrderedDict([('id', 9), ('name', 'test2'), ('hobby', 'wan'), ('age', 10)]), OrderedDict([('id', 13), ('name', 'ls'), ('hobby', None), ('age', 33)]), OrderedDict([('id', 14), ('name', 'laa'), ('hobby', None), ('age', 35)]), OrderedDict([('id', 15), ('name', 'aa'), ('hobby', 'con'), ('age', 36)]), OrderedDict([('id', 16), ('name', 'ceaaa'), ('hobby', '11'), ('age', 1111)]), Ordered Dict([('id', 17), ('name', '111'), ('hobby', ''), ('age', 222)]), OrderedDict([('id', 18), ('name', 'test33'), ('hobby', 'Play basketball'), ('age', 99)]), OrderedDict([('id', 21), ('name', 'test'), ('hobby', 'Play basketball'), ('age', 991)])] In [28]: JSONRenderer().render(p1.data) Out[28]: b'[{"id":3,"name":"test3","hobby":"\xe7\x8e\xa9\xe6\xb8\xb8\xe6\x88\x8f","age":19},{"id":4,"name":"\xe5\xbc\xa0\xe4\xb8\x89","hobby":"\xe7\x8e\xa9","age":21},{"id":5,"name":"zhaom","hobby":"play","age":112},{"id":8,"name":"\ xe9\x98\xbf\xe4\xb8\x89","hobby":"play","age":22},{"id":9,"name":"test2","hobby":"wan","age":10},{"id":13,"name":"ls","hobby":null,"age":33},{"id":14,"name":"laa","hobby":null,"age":35},{"id":15,"name":"aa","hobby":"con","age":36},{" id":16,"name":"ceaaa","hobby":"11","age":1111},{"id":17,"name":"111","hobby":"","age":222},{"id":18,"name":"test33","hobby":"\xe6\x89\x93\xe7\xaf\xae\xe7\x90\x83","age":99},{"id":21,"name":"test","hobby":"\xe6\x89\x93\xe7\xaf\xae\xe7 \x90\x83","age":991}]'
Deserialization
The process of deserialization is similar to serialization, first parsing the serialized data (json) to the native python data type (omitted), and then populating it into a serializer object.
In [29]: data ={"name":"test111","hobby":"drink","age":44} In [30]: p = ProjectSerializers(data=data) In [31]: p.is_valid() # check Out[32]: True In [33]: s.validated_data # Verified data Out[34]: OrderedDict([('name', 'test111'), ('hobby', 'drink'),
Before calling the save() method, you need to implement two methods to complete the creation and modification of the model instance. Override the create and update methods in the parent class in the ProjectSerializer class:
from rest_framework import serializers from project2s.models import Student class ProjectSerializers(serializers.Serializer): """ Project serializer """ id = serializers.IntegerField(label='student id', read_only=True) name = serializers.CharField(label='Student name') hobby = serializers.CharField(label='hobby', allow_null=True, required=False) # It is allowed to receive null, required=False. This field can be ignored when instantiating an object age = serializers.IntegerField(label='Age') c_time = serializers.DateTimeField(label='Creation time', read_only=True) def create(self, validated_data): return Student.objects.create(**validated_data) # Returns a new object def update(self, instance, validated_data): for key, value in validated_data.items(): setattr(instance, key, value) instance.save() return instance
In [35]: s.save() # The serializer instance can call save() to return a model instance directly Out[36]: <Student: name:test111,hobby:drink>
When the data verification fails, you can view the specific information through errors:
give an example:
The name field is not transferred, and the verification result is False
In [9]: data ={"name":"","hobby":"drink","age":44} In [10]: p1 = ProjectSerializers(data=data) In [11]: p1.is_valid() Out[11]: False In [12]: p1.error_messages Out[12]: {'required': 'This field is required.', 'null': 'The field cannot be empty null. ', 'invalid': 'Invalid data. Look for the dictionary type and get {datatype} . '} In [13]: p1.errors Out[13]: {'name': [ErrorDetail(string='This field cannot be empty.', code='blank')]}
Model serializer
Our ProjectSerializer class copies a lot of information from the Project model. RESTframework provides a ModelSerializer, which can automatically create the Serializer class according to the model, making the code more concise.
from rest_framework import serializers from project2s.models import Student class ProjectSerializers(serializers.ModelSerializer): class Meta: model = Student # Specify model fields = ['id', 'name', 'hobby', 'age'] # Specify the fields to serialize
You can check all fields of the serializer instance by printing its representation:
In [1]: from project2s.serializers import * In [2]: s = ProjectSerializers() In [3]: s Out[3]: ProjectSerializers(): id = IntegerField(label='ID', read_only=True) name = CharField(help_text='Student name', label='Student name', max_length=200, validators=[<UniqueValidator(queryset=Student.objects.all())>]) hobby = CharField(allow_blank=True, allow_null=True, help_text='hobby', label='hobby', max_length=200, required=False) age = IntegerField(allow_null=True, label='Age', max_value=2147483647, min_value=-2147483648, required=False)
The ModelSerializer class is just a shortcut to create the serializer class, automatically determined fields, and a simple default implementation of the create() and update() methods.