Now I will take everyone to implement an interface for adding, deleting, modifying and checking, including single query and group query, single addition and group addition, single modification and group modification, single deletion and group deletion, Let’s Go
Use of serialized components
First introduce the use of serialization components, and then introduce the source code in detail. There are three serialization components
Serializer(bottom layer),ModelSerializer(focus),ListModelSerializer(Auxiliary group reform)
Use of the Serializers component
Let's talk about Serializer first, first create a class in models.py, and then perform data migration.
class User(models.Model): SEX_CHOICES = [ [0,'male'], [1,'Female'], ] name = models.CharField(max_length=64) pwd = models.CharField(max_length=32) phone = models.CharField(max_length=11,null=True,default=None) sex = models.IntegerField(choices=SEX_CHOICES,default=0) icon = models.ImageField(upload_to='icon',default='icon/default.jpg') class Meta: db_table='user' verbose_name='user' verbose_name_plural=verbose_name def __str__(self): return '%s' %self.name
Use of ModelSerializers multi-table serialization components
Now I will take everyone to implement an interface for adding, deleting, modifying and checking, including single query and group query, single addition and group addition, single modification and group modification, single deletion and group deletion
ModelSerializer is the same as regular Serializer, but provides:
-
Automatically generate a series of fields based on the model class
-
Contains default implementations of create() and update()
-
Automatically generate validators for Serializer based on model classes, such as unique_together
-
It is not easy to cross tables with Serializer, and ModelSerializer can be used if there are foreign keys
-
For less complex logic, ModelSerializers can integrate serialization and deserialization.
model layer
It involves things that DRF novices are not familiar with. I will explain it later, and first clarify the relationship between each data table.
from django.db import models # base class class BaseModel(models.Model): is_delete = models.BooleanField(default=False) # The default is not to delete, it is 0/1 in the database create_time = models.DateTimeField(auto_now_add=True) # Set abstract = True to declare the base table, the Model as the base table cannot form a corresponding table in the database class Meta: abstract = True # Declare that the table is just an abstract table does not appear in the database # book list class Book(BaseModel): name = models.CharField(max_length=64) price = models.DecimalField(max_digits=5,decimal_places=2) img = models.ImageField(upload_to='img',default='default.jpg') #Associated Press Table publish = models.ForeignKey( to='Publish', # Associated publish table db_constraint=False, # Disassociation (Disconnect the association between the Book table and the Publish table to facilitate data deletion. Although the association is disconnected, it can still be used normally) related_name='books', # Reverse query field: publish_obj.books can find all books published by the current publishing house on_delete=models.DO_NOTHING, # Set up the connection table operation relationship ) #Associated Author Table authors = models.ManyToManyField( to='Author', db_constraint=True, #disconnect related_name='books' #reverse lookup field ) """ Define the table connection operation, and it can be pluggable,@property as a static method Then get_Book_Publish wrote serialize file field in """ @property def get_Book_Publish(self): return self.publish.name @property def get_Book_Authors(self): return self.authors.values('name', 'age') class Meta: db_table = 'book' verbose_name = 'books' verbose_name_plural = verbose_name def __str__(self): return self.name #Publisher table class Publish(BaseModel): """name,address,is_delete,create_time""" name = models.CharField(max_length=64) addres = models.CharField(max_length=64) class Meta: db_table = 'publish' verbose_name = 'publishing house' verbose_name_plural = verbose_name def __str__(self): return self.name #author list class Author(BaseModel): """name,age,is_delete,create_time""" name = models.CharField(max_length=64) age = models.IntegerField() class Meta: db_table = 'author' verbose_name = 'author' verbose_name_plural = verbose_name def __str__(self): return self.name #author details class AuthorDetail(BaseModel): """mobile, author,is_delete,create_time""" mobile = models.CharField(max_length=11) author = models.OneToOneField( to = 'Author', db_constraint = False, related_name = 'detail', on_delete = models.CASCADE ) class Meta: db_table = 'author_detail' verbose_name = 'author details' verbose_name_plural = verbose_name def __str__(self): return self.author.name
Create serializes.py in the app directory, and create serialization and deserialization classes. In fact, compared with uncomplicated logic, basically we will write in the future. It is not particularly complicated. For example, the fields of the classes obtained except for different permissions are different. In this case, others can integrate the serialization class and the deserialization class. Here we first introduce the separate writing.
from rest_framework.serializers import ModelSerializer, SerializerMethodField from . import models from rest_framework.response import Response from django.core.exceptions import ValidationError class BookModelSerializer(ModelSerializer): # Customize field information through linked tables publish_address = SerializerMethodField() def get_publish_address(self, obj): # obj is the Book object return obj.publish.addres class Meta: model = models.Book # show all fields # fields = '__all__' # show the specified field fields = ('name', 'price', 'img', 'get_Book_Publish', 'publish_address', 'get_Book_Authors') # Do not display specified fields # exclude = ('image', ) class BookModelDeSerializer(ModelSerializer): # ModelSerializer has already implemented update and create for us, we don’t have to write it ourselves # the field to be serialized class Meta: # Note that it is model, not models model = models.Book fields = ('name', 'price', 'publish', 'authors') extra_kwargs = { 'name':{ # Set the name field is required 'required': True, 'max_length': 10, 'error_messages':{ 'max_length': 'title is too long' } } } def validate_name(self, values): # Verification hook function, here is a simple verification: if the title of the book contains g, it will not work if 'g' in values: return Response({ 'status': 1, 'message': 'Book title cannot contain g' }) return values def validate(self, attrs): publish = attrs.get('publish') # If publish is a foreign key field, this is the publish object name = attrs.get('name') if models.Book.objects.filter(name=name, publish=publish): raise ValidationError({'book': 'the book already exists'}) return attrs
Single query and group query interface implementation
It is stipulated that specifying pk is a single search, and not specifying pk is a group search
from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from . import models, serializers # Create your views here. class Book(APIView): def get(self, request, *args, **kwargs): pk = kwargs.get('pk') if pk: try: book_obj = models.Book.objects.get(is_delete=False, pk=pk) return Response(1) except: return Response({ 'status':1, 'message':'no information found' }) # If no pk is written, conduct a group search else: book_obj_all = models.Book.objects.filter(is_delete=False).all() # Because the queried data is a list of queryset objects, remember to add many=True book_obj_all_ser = serializers.BookModelSerializer(book_obj_all, many=True).data return Response({ 'status':0, 'message':'success', 'result':book_obj_all_ser })
Group search test (return all data)
Single increase and group increase interface implementation
Interface: It is stipulated that passing a dictionary list from the front end is a group increase, and passing a dictionary is a new addition (these rules are set by ourselves, and there may be corresponding interface documents in the enterprise)
def post(self, request, *args, **kwargs): """ post It should be possible to realize group increase and single increase, Passing a list of dictionaries from the front end is a group increase. Passing a dictionary is a new addition :param request: :param args: :param kwargs: :return: """ request_data = request.data # deserialize if isinstance(request_data, dict) and request_data != {}: # single increase many = False elif isinstance(request_data, list) and request_data != []: # Qunzeng, in fact, the logic here is not perfect, I just demonstrate it here, just write it simply many = True else: return Response({ 'status': 1, 'message': 'Data type exception' }) book_ser = serializers.BookModelDeSerializer(data=request_data, many=many) # raise_exception=True: When the verification fails, immediately terminate the current view method, throw an exception and return to the foreground book_ser.is_valid(raise_exception=True) # Check whether it is qualified raise_exception=True Required book_obj = book_ser.save() # save an object return Response({ 'status': 0, 'msg': 'ok', 'results': serializers.BookModelDeSerializer(book_obj, many=many).data })
test:
Send data by group increase
Group check to see if the newly added data has been successfully entered into the database
It can be seen that the storage is successful!
Single delete and group delete interface implementation
def delete(self, request, *args, **kwargs): """ Single delete: yes pk,exist postman pass parameters by path Group delete:{pks:[1,2,3]} pass json pass parameters The logical idea is to turn single deletion into group deletion :param request: :param args: :param kwargs: :return: """ pk = request.GET.get('pk', None) if pk: # book_obj = models.Book.objects.filter(pk=pk).first().delete() pks = [pk] else: pks = request.data.get('pks') if not pks: return Response({ 'status':1, 'message': 'Please pass in the parameters to be changed' }) """ The logic here is to filter out pk exist pks The books inside, that is, the books to be deleted as well as is_delete=False(have not been deleted), to avoid repeated deletion then put is_delete=True,indicates that it has been deleted """ if models.Book.objects.filter(pk__in=pks, is_delete=False).update(is_delete=True): return Response({ 'status': 0, 'message':'successfully deleted' }) return Response({ 'status': 1, 'msg': 'failed to delete' })
test
Realization of single-reform and group-reform interfaces
It is divided into single partial reform, single overall reform and single partial reform.