Foreword
serializers.Serializer can serialize fields in the model model, and two methods, create and update, must be written. ModelSerializer can be regarded as an upgraded version of Serializer, which is more powerful and convenient.
In fact, the ModelSerializer class inherits the Serializer class
Serialization
Serialization is to convert the data in the database into json format and return it to the user. For details, please refer to the previous article https://www.cnblogs.com/yoyoketang/p/11538172.html
Design a Goods product table in models.py, which contains multiple fields and multiple data types.
from django.db import models # Create your models here. # Author-Shanghai Youyou QQ communication group: 717225969 # blog address https://www.cnblogs.com/yoyoketang/ class Goods(models.Model): """Product List""" goods_name = models.CharField(max_length=30, default="", verbose_name="product name") goods_code = models.CharField(max_length=30, unique=True, verbose_name="Product code") merchant_id = models.CharField(max_length=30, default="", blank=True, null=True, verbose_name="merchant ID") merchant_name = models.CharField(max_length=30, default="", blank=True, null=True, verbose_name="merchant name") goods_price = models.FloatField(blank=True, null=True, default=0, verbose_name="Product price") goods_stock = models.IntegerField(blank=True, null=True, default=0, verbose_name="item inventory") goods_groupid = models.IntegerField(blank=True, null=True, default=0, verbose_name="Product group") goods_status = models.IntegerField(choices=( (0, 'Removed'), (1, 'For Sale') ), default=1, verbose_name="0 off the shelves 1 on sale") price = models.FloatField(blank=True, null=True, default=0, verbose_name="cost price") create_time = models.DateTimeField(auto_now_add=True, verbose_name="Add Time") update_time = models.DateTimeField(auto_now=True, verbose_name="Modification time") class Meta: verbose_name_plural = 'commodity' verbose_name = "Product information" def __str__(self): return self.goods_code
view view
The view inherits drf’s APIView. Two methods are written here. Get queries all products and returns json data after serialization.
The post request is to create a product.
from rest_framework.views import APIView from rest_framework import serializers from rest_framework.response import Response from rest_framework.permissions import AllowAny, IsAuthenticated, IsAdminUser from rest_framework.authentication import TokenAuthentication from .models import Goods # Create your views here. # Author-Shanghai Youyou QQ communication group: 717225969 # blog address https://www.cnblogs.com/yoyoketang/ class GoodsSerializer(serializers.ModelSerializer): """Serialized product models""" create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S',required=False) update_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S',required=False) class Meta: model = Goods fields = '__all__' # Return all fields # exclude does not include certain fields # exclude = ["price"] class GoodsAPIView(APIView): """Product View""" permission_classes = (AllowAny,) # AllowAny allows all users def get(self, request, *args, **kwargs): """returns all """ goods = Goods.objects.all() # Query all serializer = GoodsSerializer(instance=goods, many=True) return Response({ "code": 0, "msg": "success!", "data": serializer.data }) def post(self, request, *args, **kwargs): """submit data""" verify_data = GoodsSerializer(data=request.data) if verify_data.is_valid(): save = verify_data.save() return Response({ "code": 0, "msg": "success!", "data": GoodsSerializer(instance=save).data }) else: return Response({ "code": 10086, "msg": "Illegal parameter", "data": verify_data.errors })
urls.py configures access routing
from django.conf.urls import url from yoyo import views urlpatterns = [ url('^api/v1/goods/$', views.GoodsAPIView.as_view()), ]
Serialization and Deserialization
What is serialization?
When users need to query data, the data in the database is converted into the json data we need. This process is serialization.
Instantiate the GoodsSerializer object in the get method and pass 2 parameters
- Instance is the queryset object of the query, or it can be the object object of a single Goods
- many If it is a queryset object, you need to bring many=True, indicating that it is a list with multiple data. If it is a single object object, you do not need this parameter.
def get(self, request, *args, **kwargs): """returns all """ goods = Goods.objects.all() # Query all serializer = GoodsSerializer(instance=goods, many=True)
The above process is serialization. After serialization, the data is output serializer.data
What is deserialization?
When users add products, they need to save the data to the database. In this process, we need to first verify whether it is legal.
For the data passed in by the user, we need to clean it first, because the user may pass some fields that are not in the database table, and we do not need these, so we can use GoodsSerializer(data=request.data)
- data The parameters passed in by the user are obtained through request.data. request.data is actually the same as the previous request.POST to obtain the data passed by the user.
- is_valid() Verifies whether the data is legal
- save() must call is_valid() before saving, and return a Goods object after saving.
def post(self, request, *args, **kwargs): """submit data""" verify_data = GoodsSerializer(data=request.data)
In the above process, the data passed by the user is first cleaned, the legality of the data is verified, and then the process is stored in the database, which is deserialization.
Item required to verify user data required=True
Those who have read the interface document should know that some parameters are required and some are not required. Then we can control the required and non-required fields in GoodsSerializer
For details, please refer to the previous article https://www.cnblogs.com/yoyoketang/p/14291206.html
class GoodsSerializer(serializers.ModelSerializer): """Serialized product models""" create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S',required=False) update_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S',required=False) #Required fields goods_code = serializers.CharField(required=True) goods_stock = serializers.IntegerField(required=True) class Meta: model = Goods fields = '__all__' # Return all fields
When serializing, set goods_code and goods_stock as required fields. Then when adding goods, you will be prompted if they are not passed.
{"goods_code":["This field is required."],"goods_stock":["This field is required."]}}
Validation ignores some fields read_only=True
If there are some fields that I don’t want users to modify when creating a product, such as goods_status (product status), the default is for sale,
You don’t want users to set off the shelf when creating, so you can ignore the goods_status field and set read_only=True
# Author-Shanghai Youyou QQ communication group: 717225969 # blog address https://www.cnblogs.com/yoyoketang/ class GoodsSerializer(serializers.ModelSerializer): """Serialized product models""" create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S',required=False) update_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S',required=False) #Required fields goods_code = serializers.CharField(required=True) goods_stock = serializers.IntegerField(required=True) # Ignore the field and set read_only=True goods_status = serializers.IntegerField(read_only=True) class Meta: model = Goods fields = '__all__' # Return all fields
Now no matter what goods_status is passed, it will not affect the saved result.
Verify string and integer range
Verify goods_code string length is 8-15 digits, verify goods_stock integer range is 1-10000
class GoodsSerializer(serializers.ModelSerializer): """Serialized product models""" create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S',required=False) update_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S',required=False) #Required fields goods_code = serializers.CharField(required=True, max_length=15, min_length=8) goods_stock = serializers.IntegerField(required=True, min_value=1, max_value=10000) # Ignore the field and set read_only=True goods_status = serializers.IntegerField(read_only=True) class Meta: model = Goods fields = '__all__' # Return all fields
At this time, the incoming string and integer range will be verified.
Customized verification field
If I want to name the user’s product code, it must start with sp and write a separate verification method for a certain field. You can customize validate_
- The value parameter is the data passed in
- The exception thrown by raise will be serializers.ValidationError(“goods_code does not start with sp”) and will be displayed in
verify_data.errors
# Author-Shanghai Youyou QQ communication group: 717225969 # blog address https://www.cnblogs.com/yoyoketang/ class GoodsSerializer(serializers.ModelSerializer): """Serialized product models""" create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S',required=False) update_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S',required=False) #Required fields goods_code = serializers.CharField(required=True, max_length=15, min_length=8) goods_stock = serializers.IntegerField(required=True, min_value=1, max_value=10000) # Ignore the field and set read_only=True goods_status = serializers.IntegerField(read_only=True) def validate_goods_code(self, value): """Validate field validate_<Field>""" if not value.startswith("sp"): raise serializers.ValidationError("goods_code does not start with sp") return value class Meta: model = Goods fields = '__all__' # Return all fields
Multiple field verification
If I want to check that goods_price (product sales price) cannot be less than (price) cost price, if any operation sets the product price lower than the cost price, it will be a big loss!
This involves mutual verification of the two values of the incoming parameters.
# Author-Shanghai Youyou QQ communication group: 717225969 # blog address https://www.cnblogs.com/yoyoketang/ class GoodsSerializer(serializers.ModelSerializer): """Serialized product models""" create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S',required=False) update_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S',required=False) #Required fields goods_code = serializers.CharField(required=True, max_length=15, min_length=8) goods_stock = serializers.IntegerField(required=True, min_value=1, max_value=10000) # Ignore the field and set read_only=True goods_status = serializers.IntegerField(read_only=True) def validate_goods_code(self, value): """Validate field validate_<Field>""" if not value.startswith("sp"): raise serializers.ValidationError("goods_code does not start with sp") return value def validate(self, attrs): """Custom verification""" goods_price = attrs.get('goods_price', 0) price = attrs.get('price', 0) if goods_price < price: raise serializers.ValidationError('goods_price cannot be less than price') return attrs class Meta: model = Goods fields = '__all__' # Return all fields