DRF (seven)

I. Preparation:

1. The main routes:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/', include('api.urls')),
]

2.api route:

from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'^cars/$', views.CarModelViewSet.as_view({
        'get': 'list',
        'post': 'create'
    })),
    url(r'^cars/(?P<pk>.*)/$', views.CarModelViewSet.as_view({
        'get': 'retrieve',
        'put': 'update',
        'patch': 'partial_update',
        'delete': 'destroy'
    })),
]

3.setting.py:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'api.apps.ApiConfig',

    'rest_framework',

]

4.models:

from django.db import models


class BaseModel(models.Model):
    is_delete = models.BooleanField(default=0)
    create_time = models.DateTimeField(auto_now_add=True)
    class Meta:
        abstract = True

class Car(BaseModel):
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    brand = models.ForeignKey('Brand', db_constraint=False, on_delete=models.DO_NOTHING, related_name='cars')

    @property
    def brand_name(self):
        return self.brand.name

    class Meta:
        db_table = 'old_boy_car'
        verbose_name = '汽车'
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.name

class Brand(BaseModel):
    name = models.CharField(max_length=16)
    class Meta:
        db_table = 'old_boy_brand'
        verbose_name = '品牌'
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.name

The view class:

class CarModelViewSet(ModelViewSet):
    queryset = models.Car.objects.filter(is_delete=False)
    serializer_class = serializers.CarModelSerializer

    def destroy(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        try:
            car_obj = models.Car.objects.get(pk=pk, is_delete=False)
            car_obj.is_delete = True
            car_obj.save()
            return Response({
                'status': 0,
                ' MSG ' : ' successfully deleted ' 
            }) 
        the except :
             return the Response ({
                 ' Status ' :. 1 ,
                 ' MSG ' : ' delete failed ' 
            })
   def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
return Response({
'status': 0,
'msg': 'ok',
'results': response.data
})
 

II routing component (the write information is preceded by 'cars' to, known automatic completion packet pk):

from . Import views
 from rest_framework.routers Import SimpleRouter
 # initialization-routing objects 
Router = SimpleRouter () 

# registration various interfaces routing 
router.register ( ' cars ' , views.CarModelViewSet, base_name = ' CAR ' )
 # router.register (' Brands ', views.BrandModelViewSet, base_name =' Brand ') 

the urlpatterns = [] 
urlpatterns.extend (router.urls)

III. The search component

Mainly using mixins.ListModelMixin class QuerySet found, further searching, filtering, sorting and other operations

There are two classes in SearchFilter and OrderingFilter filters.py file:

class SearchFilter(BaseFilterBackend):
    # The URL query parameter used for the search.
    search_param = api_settings.SEARCH_PARAM   默认是search
    template = 'rest_framework/filters/search.html'
    lookup_prefixes = {
        '^': 'istartswith',
        '=': 'iexact',
        '@': 'search',
        '$': 'iregex',
    }
    search_title = _('Search')
    search_description = _('A search term.')

It requires two parameters:

    def filter_queryset(self, request, queryset, view):
        search_fields = self.get_search_fields(view, request)
        search_terms = self.get_search_terms(request)

Custom view class written:

    from rest_framework.filters import SearchFilter, OrderingFilter
    # Search Component 
    # interfaces:?? / Cars / search = Qin || / cars / search = 1 fuzzy search in name and price of the two fields 
    filter_backends = [searchfilter]
     # default fuzzy query, equivalent to $, beginning with what ^ exact match = @? ? 
    = search_fields [ ' name ' , ' . price ' ]

IV. Sort component (support reverse)

    filter_backends = [SearchFilter, OrderingFilter]
    ordering_fields = ['pk', 'price']
   # 接口: api/cars/?search=1&ordering=-pk

V. screening components

installation:

pip install django-filter

Configuration:

= The INSTALLED_APPS [ 
    ... 
    ' django_filters ' ,   # need to register the application, 
]
 
global (can also be provided locally): REST_FRAMEWORK
= { ... ' DEFAULT_FILTER_BACKENDS ' : ( ' django_filters.rest_framework.DjangoFilterBackend ' ,) }

View class:

    
   from .filtersets import CarFilterSet

# Screening (classification section) filter_backends = [searchfilter, OrderingFilter, DjangoFilterBackend] # Category: field generally can be grouped # filter_fields = [ 'Brand'] # interval, classification may also comprise, screened to promote this manner filter_class = CarFilterSet

Interval categories:

from django_filters.rest_framework import FilterSet
from django_filters import filters
from . import models
class CarFilterSet(FilterSet):
    min_price = filters.NumberFilter(field_name='price', lookup_expr='gte')
    max_price = filters.NumberFilter(field_name='price', lookup_expr='lte')
    class Meta:
        model = models.Car
        # Brand to classify or 
        # MIN_PRICE, can define the interval of max_price 
        Fields = [ ' Brand ' , ' MIN_PRICE ' , ' of max_price ' ]

VI. Paging component

Page views:

 # Page 
    # Normal tab (most common) 
    # pagination_class = pagination.CarPageNumberPagination 
    # offset tab 
    # pagination_class = pagination.CarLimitOffsetPagination 
    # encryption tab 
    pagination_class = pagination.CarCursorPagination

Custom pagination.py:

from rest_framework.pagination Import PageNumberPagination
 # ordinary paging 
class CarPageNumberPagination (PageNumberPagination):
     # default under a number 
    PAGE_SIZE. 3 = # user may customize a number of selected, but a maximum of 5 bar 
    page_size_query_param = ' PAGE_SIZE ' 
    MAX_PAGE_SIZE. 5 = # the default number of access / cars / page = page number? #        EG:? / cars / page = 1 # ? customize the number of access / cars / page = page number & page_size = one of the number #        EG: / cars / ? Page = 5 = 1 & PAGE_SIZE from rest_framework.pagination Import LimitOffsetPagination
 # offset pagination class
    
    
    
    
    



CarLimitOffsetPagination (LimitOffsetPagination):
     # default page number of 
    default_limit. 3 = # number of a display control limit, offset number of offset control (counting from the beginning) 
    limit_query_param = ' limit ' 
    offset_query_param = ' offset ' # restrictions limit the maximum number display bar can be set 
    max_limit =. 5 # Interface / cars / number of limit = one of & offset = offset the number? #        EG:? / cars / limit =. 5 & offset = 2 # display 3 to 7 from rest_framework .pagination Import CursorPagination
 # encryption paging class CarCursorPagination (CursorPagination):
     # default page number of
    
    
    
    





    =. 3 PAGE_SIZE # user may customize a number of selected, but a maximum of 5 bar 
    page_size_query_param = ' PAGE_SIZE ' 
    MAX_PAGE_SIZE =. 5
     # default collation 
    Ordering = ' PK ' # default ordering access / cars /? cursor = encryption string #        EG: / cars / Cursor = cD0z? # binding view class OrderingFilter implement custom collation #   / cars / Cursor encryption string = & ordering = sort field? #        EG: / cars / Cursor = cD0z & ordering = -Price?
    
    
    
    
    
    

VII. Exception Handling

Configuration:

# drf配置
REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'api.exception.exception_handler'
}

Custom exception:

# Rest_framework.views exception_handler under abnormal processing all drf controllable range 
from rest_framework.views Import exception_handler AS drf_exception_handler
 # abnormal drf or to drf_exception_handler, we only have to deal drf unhandled exception 

from rest_framework.response Import the Response 

# exception handler custom reasons: to exception log records by logging 
DEF exception_handler (EXC, context): 
    Response = drf_exception_handler (EXC, context) 

    IF Response iS None:
         # DRF exception processing can not 
        return the Response ({
             ' exception ' : 'Server abnormal ' , 
        }, Status = 500 ) 

    response.exception = True
     return Response

VIII. Interface documentation (yapi)

 

Guess you like

Origin www.cnblogs.com/sima-3/p/11502870.html