DRF sequence of assembly

A. DRF sequence of

  django comes sequence of components, but the sequence of compared rest_framework poor, so this is not mentioned django carrying a serialization component.

  First rest_framework using the same sequence of components from the component is somewhat similar, when the front end of the data deserialized back, you need to verify is_valid call, which also has hooks validate_ local field names, after the validate the global hook, before checking is_valid call .data and .errors.

  rest_framework There are two ways to serialize, are inherited Serializer and ModelSerializer, if the serialized data is multiple, be sure to specify many = True, or will be error. many = True and False difference is that the former returns a list of sets of the dictionary, which is only a dictionary, a data that is on.

from rest_framework.serializers import Serializer, ModelSerializer

 1.1 inherit the serialization Serializer

  models.py code as follows:

from django.db Import Models 

# the Create your Models here Wallpaper. 


class Book (models.Model): 
    title = models.CharField (MAX_LENGTH = 32 ) 
    . price = models.IntegerField ()
     # db_constraint time = False, many logic table exists only relation on, regardless of the data processing foreign key relationships, but still can be used normally ORM 
    # on_delete default is cASCADE in django1 versions, namely cascading deletes. on_delete four options, SET_NULL i.e. a foreign key correspondence table 
    # data deleted, this field is set to null, null = True or to set default 
    # the related_name = 'reverse query based on the name of' 
    # foreign key table corresponding to point the name .all to query the data based on multi-relational tables, table name does not need to get the lowercase + _set.all 
    publish = models.ForeignKey ( " publish " , the related_name = 'books', db_constraint=False, on_delete=models.SET_NULL, null=True)
    authors = models.ManyToManyField("Author", db_constraint=False)

    def __str__(self):
        return self.title


class Publish(models.Model):
    name = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name


class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    def __str__(self):
        return self.name

  Class BookSerializer following sequence:

class BookSerializer (serializers.Serializer): 
    title = serializers.CharField (MAX_LENGTH = 32 ) 
    . price = serializers.IntegerField ()
     # action source is very strong, which corresponds to a value self.publish.name, 
    # when there are choices attribute fields using can be specified when source = 'get_ field name _display' to obtain directly the corresponding value 
  # Source If a field, the field will show, if the method, the method will be executed, without parentheses 
    publish = serializers.CharField (Source = ' publish.name ' )
     # can specify a function, the function name is fixed get_ field name, is the return value of the function value of the field 
    # READ_ONLY not pass deserialization, WRITE_ONLY is not displayed when serializing 
    author_detail = serializers.SerializerMethodField (READ_ONLY = True) 

    #Return value of the function is the value of the field author_detail 
    DEF get_author_detail (Self, book_obj): 
        the authors = book_obj.authors.all ()
         # internal function may be called other sequences directly class 
        return AuthorSerializer (the authors, MANY = True) .data 

    # local hook 
    DEF validate_title (Self, value):   # value is the current value in the title of 
        from rest_framework Import Exceptions
         IF  ' H '  in value:
             # this is the information stored in the check does not pass in the sequence of obj.errors 
            the raise exceptions.ValidationError ( ' h h, it is impossible ' )
        return value 

    # global hook 
    DEF the validate (Self, attrs):   # attrs containing all the fields and the dictionary data 
        from rest_framework Import Exceptions
         IF attrs.get ( ' title ' ) == attrs.get ( ' . price ' ):
             return attrs
         the else :
             The raise exceptions.ValidationError ( ' title and how the same price ' )

  Note that only trigger when either local or global hook hook function, must go is_valid serialized object methods, but the global need to serialize all fields triggered by check only.

  AuthorSerializer above needs as follows:

# 作者Author序列化类
class AuthorSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=32)
    age = serializers.IntegerField()

  After writing the data in the table, write CBV in view views.py inheritance ListAPIView:

from rest_framework.generics import ListAPIView
from app01 import models
from app01 import app01serializers
# Create your views here.


class BookAPIView(ListAPIView):
    queryset = models.Book.objects
    serializer_class = app01serializers.BookSerializer

  Then open the route:

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^books/', views.BookAPIView.as_view()),
]

  The interface is then tested with a postman:

  Here we must note that if the front-end back end post submit a request to create a new data to deserialize, then call is_valid check the data before you can call .dada and .errors. Because inheritance Serializer is not specified in the table, we need to create the serialization class override the corresponding method, the .dada when create the parameters passed, and then create stored in the write logic, if it comes to multi-table, then to the full to write on their own logic, and other parameters table before is_valid will need to remove the save operation can be executed in the view.

  You need to be assigned to the parameter when the deserialized data:

bs=BookSerializer(data=request.data)

   If intence parameters and data parameters are given a value, it will perform updates:

def put(self, request, pk):
        book_obj = models.Book.objects.filter(pk=pk).first()

        bs=BookSerializers(data=request.data, instance=book_obj)
        if bs.is_valid():
            bs.save() # update
            return Response(bs.data)
        else:
            return Response(bs.errors)    

 1.2 serialization of inherited ModelSerializer

  Serialization inherited Modelserializer more convenient, because no one by writing field types and field.

  Sequence of categories as follows:

class BookSerializer (serializers.ModelSerializer):
     # generate a third embodiment publish_detail 
    publish = PublishSerializer () 

    class Meta -: 
        Model = models.Book
         # Fields = '__all__ is' sequences of all fields, but in general we do not use this method 
        # general in the following ways, which can fill in a form field have, 
        # can also write the foreign key column of the table, many to many table field forward or reverse the corresponding dot syntax used 
        # during which we generally use the reverse lookup. lowercase table names way, you can set the field related_name in foreign = 'reverse name after the dot syntax query' 
        # when the foreign key column for the table such as book publish setting properties related_name = 'books', then Publish reverse lookup table books, 
        # .books_all ( ) to get all the books published by the objects (or else write .book_set.all ()) 
        Fields = [ ' title ' , '. price ' , ' publish ' , ' author_detail ' ]
         # the exclude = (' title ',) # out all fields except title can not be used simultaneously with Fields 
        # depth = depth control. 1 #, write several layers to get inside, the more layers, the slower the response, the official suggested between 0-10, personally recommend up to three layers

  ModelSerializer inherited classes can also write global hook, a local hook, and the processing of the field, but has been ordered to write outside of the class Meta.

  fields can be written with a field model table that contains the foreign key field and ManyToMany field, when specified related_name, reverse lookup table can be written to access related_name specify the name of another table.

  Here mention a mouth, rest_framework provides depth attribute depth, but not recommended, because it is not controllable too. Generally when it comes to multi-table, we have carried out in the model table, such as author_detail here, it is the author of all objects-many relationship table corresponding book, we add the following methods in the Book model table:

@property
def author_detail(self):
    result_list = []
    authors = self.authors.all()
    for author in authors:
        dic = {'name': author.name, 'age': author.age}
        result_list.append(dic)
    return result_list

  Publish the above can also be defined in the model table, such as writing publish_detail:

# 生成publish_detail方式一
@property
def publish_detail(self):
    publish_obj = self.publish
    return {'name': publish_obj.name, 'email': publish_obj.email}

# 生成publish_detail方式二
@property
def publish_detail(self):
    from app01 import app01serializers
    publish_obj = self.publish
    return app01serializers.PublishSerializer(publish_obj).data

  Then the sequence of categories to publish publish_detail, a postman test interface:

  结果是一样的,继承ModelSerializer因为需要指定模型表,所有不需要重写create方法,直接调用.save方法即可。

1.3 模型层中参数的补充

  比如当我们创建外键关系与多对多关系表时,django 1.x版本默认都是级联删除的,即on_delete=CASCADE,而django 2.x版本需要自己指定。

  on_delete一共有四个值可以选择:

1. on_delete = models.SET_NULL  # 关联表字段删除后,该ForeignKey字段的值置为空,需要设置null=True或者是设置default
2. on_delete = models.SET_DEFAULT # 关联表字段删除后,该ForeignKey字段的值置为默认值,需要设置default字段
3. on_delete = models.DO_NOTHING # 关联表字段删除后,该ForeignKey字段的值不变
4. on_delete = models.CASCADE # 关联表字段删除后,级联删除

   Foreign与ManyToMany字段还有db_constraintrelated_name字段。指定db_constraint=False时,一对多的表只存在逻辑上的关系(此时数据库如navicat中表关系图它们之间的线会断开),处理数据无需考虑外键关系,不过依旧可以使用ORM正常操作正反向查询等。

  指定related_name字段时,反向查询无需按表名小写的方式,直接点该related_name定义的字段即可。举例,比如Book表与Author表一对多,外键在Book表中,那么Author查询Book表的数据就是反向查询,需要author_obj.book_set.all()获取作者对应的所有书籍数据。这时指定related_name='books',那么只需采用author_obj.books.all()即可。

  如果不清楚可以再看看该博客:https://www.cnblogs.com/liuqingzheng/articles/9766376.html

 

Guess you like

Origin www.cnblogs.com/maoruqiang/p/11228922.html