后端开发软件目录规范

一.Model

from django.db import models

# Create your models here.
# 多表的设计
# 图书 作者 出版社 作者详情表

# 基表的创建主要是我们的字段都有共同的字段抽离

class BaseModel(models.Model):
    # 相同的字段
    is_delete = models.BooleanField(default=False)
    create_time = models.DateTimeField(auto_now_add=True)

    # 在建基表的时候要设置 abs 来声明基表,作为基表的model 不能再数据库中行成对应的表

    class Meta:
        abstract = True

class Book(BaseModel):
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    img = models.ImageField(upload_to='img', default='img/default.jpg/')
    # 外键字段的建表规则健在查询频率少的那张表 效率的问题
    # 多对对外键健在那张表都可以
    authors = models.ManyToManyField(to='Author',
                                     db_constraint=False,
                                     related_name='books')

    publisher = models.ForeignKey(
        to='Publish',
        related_name='books',  # 反向查字典的关键字publish_obj.books就能访问改出版社的所有书籍

        on_delete=models.DO_NOTHING,
    db_constraint=False)

    class Meta:
        db_table = 'book'
        verbose_name = '书籍表'
        verbose_name_plural = verbose_name

    @property
    def author_list(self):
        # 查表 作者有多个值的
        return self.authors.values('name', 'age','detail__addr','detail__phone').all()

    @property
    def publish_name(self):
        # 正向按字段
        return self.publisher.name

    def __str__(self):
        return "<%s>" % self.name

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

    class Meta:
        db_table = 'author'
        verbose_name = '作者表'
        verbose_name_plural = verbose_name

    def __str__(self):
        return "%s" % self.name

class Publish(BaseModel):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=32)

    class Meta:
        db_table = 'publish'
        verbose_name = '出版社表'
        verbose_name_plural = verbose_name

    def __str__(self):
        return "%s" % self.name

class AuthorDetail(BaseModel):
    addr = models.CharField(max_length=32)
    phone = models.CharField(max_length=11, null=True)

    # 外键字段一对多还是建立多方
    # 一对一就健在查询评率低的一方
    # 一对一的cascade是同步的进行同删同减
    author_detail = models.OneToOneField(to='Author',
                                         db_constraint=False,
                                         related_name='detail',
                                         on_delete=models.CASCADE)

    class Meta:
        db_table = 'author_detail'
        verbose_name = '详情表'
        verbose_name_plural = verbose_name

    def __str__(self):
        return "%s" % self.author_detail.name

api 或者项目名下的__init__

import pymysql
pymysql.install_as_MySQLdb()

二.settings

数据库和全局文件的配置 图片的暴露接口

"""
Django settings for day71_djproj project.

Generated by 'django-admin startproject' using Django 1.11.11.

For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '^zqxsy^v6z)!9klipb^^3@=txceu7^b4!-rsp#8r55&_u^p11h'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

# Application definition

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'
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'day71_djproj.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'day71_djproj.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day71_dj',
        'USER': "root",
        ',
        'HOST':"127.0.0.1",
        'PORT': 3306
    }
}

# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = False

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = '/static/'

# 图片
MEDIA_URL = '/media/'

# 图片的更目录的配置
MEDIA_ROOT = os.path.join(BASE_DIR,'/media/')

# 我们还要配置解析的全局配置文件 如果想要配置局部的就要在我们自己的类函数下进行配置 方法

# 配置响应的全局文件

# 配置自定义的异常文件的全局的配置
# 自定义drf配置爱-全局响应配置
REST_FRAMEWORK = {
    # drf提供的渲染类
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],

    # drf提供类解析的数据包的格式  请求格式 再取全局进行配置 全局 进而进行局部的的设置
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
        'rest_framework.parsers.MultiPartParser',
    ],
    # 全局配置异常模块 自定有异常模块
    'EXCEPTION_HANDLER': 'api.exception.exception_handler',
}

准备事项配置好后 model 表的迁移命令

(1)

D:\day71_djproj>python manage.py makemigrations

(2)python  manage.py migrate

或者快捷键

三.admin

注册超级用户 createsuperuser()

将我们的model 模型表一一注册到我们的admin 中>>> 数据的新增 (方便测试)

from django.contrib import admin
from api import models
# Register your models here.

admin.site.register(models.Author)
admin.site.register(models.Book)
admin.site.register(models.AuthorDetail)
admin.site.register(models.Publish)

四.URL 路由的匹配

(1)总路由 >>>实现陆游的分发

from django.conf.urls import url, include
from django.contrib import admin
# from django.conf.urls import url
# 资源暴露给外部 必须配置在全局的
# 渲染图片 接口暴露给外部\
from day71_djproj import settings
from django.views.static import serve

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

    url(r'^media/(?P<path>.*)', serve, {'document_root':settings.MEDIA_ROOT}),
]

(2)项目api下的路由

from django.conf.urls import url
from api import views
# 路由模块:为标准的viweset接口提供路径的简写方式
from django.conf.urls import include
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
# 路径对象进注册
router.register('v6/books',views.BookModelViewSet)

urlpatterns = [

    url(r'^books/$',views.V2Book.as_view()),
    url(r'^books/(?P<pk>.*)/$',views.V2Book.as_view()),
    url(r"^v1/books/$",views.BookApIView.as_view()),
    url(r"^v1/books/(?P<pk>.*)/$", views.BookApIView.as_view()),

    url(r"^v2/books/$", views.BookGenericAPIView.as_view()),
    url(r'^v2/books/(?P<pk>.*)/$', views.BookGenericAPIView.as_view()),

    url(r"^v3/books/$", views.BookMixinGenericAPIView.as_view()),
    url(r'^v3/books/(?P<pk>.*)/$', views.BookMixinGenericAPIView.as_view()),
    url(r"^v4/books/$", views.BookListCreateAPIView.as_view()),
    url(r'^v4/books/(?P<pk>.*)/$', views.BookListCreateAPIView.as_view()),
    url(r"^v5/books/$", views.BookGenericViewSet.as_view({"get": "my_get_list"})),
    url(r'^v5/books/(?P<pk>.*)/$', views.BookGenericViewSet.as_view({"get": "my_get_obj"})),
    url(r"^vv/books/$", views.MyRequest.as_view()),
    url(r'^vv/books/(?P<pk>.*)/$', views.MyRequest.as_view()),

    url(r'^v7/books/$',views.BookModelViewSet.as_view({"get":'list','post':'create'})),
    url(r'^v7/books/(?P<pk>.*)/$',views.BookModelViewSet.as_view({'get':'retrieve','put':'update','patch':'partial_update','delete':'destroy'})),

    # 在下面进行分发应用匹配
    url(r'^',include(router.urls))

]

五.视图函数

from django.shortcuts import render

from . import serializers
from api import models
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response

from utils.response import APIResponse

class V2Book(APIView):
    # 单查
    # 群查
    def get(self, request, *args, **kwargs):
        # print(request.query_params,12312)
        pk = kwargs.get('pk')
        if pk:
            try:
                book_obj = models.Book.objects.get(pk=pk, is_delete=False)
                print(book_obj, type(book_obj), 3212)
                book_data = serializers.BookModelSerializer(book_obj).data
                # print(book_data,type(book_data),123)
                return Response({
                    'status': 1,
                    'msg': 'ok',
                    'results': book_data
                })
            except:
                return Response({
                    "status": 0,
                    'img': "数据有误"
                })
        else:
            book_query = models.Book.objects.filter(is_delete=False).all()

            book_data = serializers.BookModelSerializer(book_query, many=True).data

            return Response({
                'status': 1,
                'msg': 'ok',
                'results': book_data
            })

        # 反序列化的 通过序列化组件
        # user_ser = serializer

    def post(self, request, *args, **kwargs):
        # 单增数据是与model对应的字典   获取的数据的格式和类型的检验
        request_data = request.data
        print(request_data)
        # if not isinstance(request_data,dict) or request_data == {}:
        #     return Response({
        #         'status': 1,
        #         'msg': '数据有误',
        #
        #     })
        # else:
        # 单增
        if isinstance(request_data, dict) and request_data != {}:
            many = False
            book_data = serializers.BookModelSerializer(data=request_data, many=many)  # 进行反序列化的对象赋值
            # 当前视图异常是 立即出发报错异常的进行返回到前端

            book_data.is_valid(raise_exception=True)  # 进行数据的检验
            data_result = book_data.save()
            return Response({
                'status': 1,
                'msg': 'ok',
                'results': serializers.BookModelSerializer(data_result).data  # 反序列化
            })
        elif isinstance(request_data, list) and request_data != []:  # 是多个值的话 同时新增多个对象
            many = True
            book_data = serializers.BookModelSerializer(data=request_data, many=many)  # 反序列化 再存
            book_data.is_valid(raise_exception=True)  # 进行数据的检验
            # ???
            data_result = book_data.save()
            return Response({
                'status': 1,
                'msg': 'ok',
                'results': serializers.BookModelSerializer(data_result, many=many).data  # 反序列化
            })

        else:
            return Response({
                'status': 0,
                'msg': '数据格式有误'
            })
        # 获取数据
        # 全增

    def delete(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        if pk:
            # pk__in 符合下面的要求
            pks = [pk]
        else:
            pks = request.data.get('pks')
        if models.Book.objects.filter(pk__in=pks, is_delete=False).update(is_delete=True):
            # 直接返回
            return Response({
                'status': 1,
                'msg': '删除成功'
            })
        else:
            return Response({
                'status': 0,
                'msg': '删除未成功'

            })

    def put(self, request, *args, **kwargs):
        # 单 整体修改
        # 序列化的是对象

        pk = kwargs.get('pk')

        book_obj = models.Book.objects.filter(pk=pk).first()

        #  反序列化 数据
        request_data = request.data
        # 反序列化的对数据进行修改的三件事 1.数据是改谁的 2.将数据进行data 封装 3.完序列化后的数据的检验
        # 反序列化的是传的对象的 和值
        book_ser = serializers.BookModelSerializer(instance=book_obj, data=request_data, )
        # 反序列化传数据 还需要修改的对象
        # 检验
        book_ser.is_valid(raise_exception=True)
        # 修改入库
        result_obj = book_ser.save()  # 修改入库
        return Response({
            'status': 1,
            'msg': '修改成功',
            # 返回的 是序列化对象 传入的是save() 返回的对象
            'results': serializers.BookModelSerializer(result_obj).data
        })

    # 进行单改和全改的patch()
    # 单体pk = [1,]
    # 多改pk=[1,2,3]

    def patch(self, request, *args, **kwargs):
        pk = kwargs.get("pk")
        request_data = request.data
        # 单改
        if pk and isinstance(request_data, dict):
            pks = [pk, ]
            request_data = [request_data, ]
        # 群改
        elif not pk and isinstance(request_data, list):
            pks = []
            #
            for data in request_data:
                # 将每个数据中的字典进行删除(本质是返回键)
                pk = data.pop('pk', None)
                if pk:
                    pks.append(pk)
                else:
                    return Response({
                        'status': 0,
                        'msg': '数据有误'
                    })
        else:
            return Response({
                "status": 0,
                'msg': "数据有误"
            })
        # 将上面的单改和群对象改进行逻辑业务处理
        # 我们需要处理的是pks中 and健值绑定的没有数据的pks 进行删除
        # 将合理的数据进保存
        objs = []
        new_data = []
        for index, pk in enumerate(pks):
            try:
                # 存储合理的数据进行修改
                obj = models.Book.objects.get(pk=pk, is_delete=False)  # BUG
                objs.append(obj)
                # 将对应上的数据保存
                new_data.append(request_data[index])
            except:
                # 继续循环 循环结束继续结束
                continue
        # 统一的逻辑
        book_ser = serializers.BookModelSerializer(instance=objs, data=new_data, partial=True, many=True)
        # 校验
        book_ser.is_valid(raise_exception=True)
        print(book_ser, 123)
        book_obj = book_ser.save()
        print(book_obj, 555)
        # 返回
        return Response({
            'status': 1,
            'msg': '修改成功',
            # 序列化和反序列化只要有多个必须是many = TRUE
            'results': serializers.BookModelSerializer(book_obj, many=True).data
        })

# 重写response() 响应方法
class BookApIView(APIView):
    def get(self, *args, **kwargs):
        book_query = models.Book.objects.filter(is_delete=False).all()
        book_ser = serializers.BookModelSerializer(book_query, many=True)
        # print(book_ser)
        book_data = book_ser.data  # 数据是存放在data 中的
        # print(book_data)
        # 返回数据我们用封装号的
        return APIResponse(results=book_data)

# Genseric 类
from rest_framework.generics import GenericAPIView

class BookGenericAPIView(GenericAPIView):
    # 因为我们继承的是GenericAPIView   >>> 继承APIView
    # queryset = None 和serializer = None 初始值为空时需要我们进行重写的
    queryset = models.Book.objects.filter(is_delete=False)

    serializer_class = serializers.BookModelSerializer

    # 单查 pk get的方法

    lookup_field = 'pk'

    # def get(self, request, *args, **kwargs):
    #     book_query = self.get_object()
    #     print(book_query, 55)
    #     book_ser = self.get_serializer(book_query)
    #     book_data = book_ser.data
    #     return APIResponse(results=book_data)

    # 群查
    def get(self, request, *args, **kwargs):
        book_query = self.get_queryset()
        book_ser = self.get_serializer(book_query,many=True)  # 这里加上many=True
        book_data = book_ser.data
        return APIResponse(results=book_data)

"""

# 1)mixins有五个工具类文件,一共提供了五个工具类,六个工具方法:单查、群查、单增、单删、单整体改、单局部改
# 2)继承工具类可以简化请求函数的实现体,但是必须继承GenericAPIView,需要GenericAPIView类提供的几个类属性和方法(见上方GenericAPIView基类知识点)
# 3)工具类的工具方法返回值都是Response类型对象,如果要格式化数据格式再返回给前台,可以通过 response.data 拿到工具方法返回的Response类型对象的响应数据
"""
# mixins 有五大工具六大方法
from rest_framework.mixins import ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin

class BookMixinGenericAPIView(ListModelMixin,CreateModelMixin,UpdateModelMixin,RetrieveModelMixin,GenericAPIView):
    # 先获取对象
    queryset = models.Book.objects.filter(is_delete=False)
    # 重写序列化
    serializer_class = serializers.BookModelSerializer

    # get 查询
    def get(self,request,*args, **kwargs):
        # mixins 中的单查 pk
        if 'pk' in kwargs:

            response = self.retrieve(request,*args,**kwargs)
        else:
            # mixins提供的list方法的响应对象是Response,想将该对象格式化为APIResponse
            response = self.list(request, *args, **kwargs)
            # 数据都是封装在response

        return APIResponse(results=response.data)

    # 单增post 多增的操作
    def post(self, request, *args, **kwargs):
        response = self.create(request, *args, **kwargs)
        return APIResponse(results=response.data)

    # =更新put
    # 注意必须在pk = 22 有值的情况 也必须是在url 中拼接pk 才能进行目前的修改
    def put(self,request, *args, **kwargs):
        response = self.update(request, *args, **kwargs)
        return APIResponse(results=response.data)

    # patch修改 也会需要 pk url 中拼接
    def patch(self,request, *args, **kwargs):
        response = self.update(request, *args, **kwargs)
        return APIResponse(results=response.data)

# 工具视图
"""
# 1)工具视图都是GenericAPIView的子类,且不同的子类继承了不听的工具类,重写了请求方法
# 2)工具视图的功能如果直接可以满足需求,只需要继承工具视图,提供queryset与serializer_class即可
"""
# 群查 局部更新

from rest_framework.generics import ListCreateAPIView,UpdateAPIView
class BookListCreateAPIView(ListCreateAPIView, UpdateAPIView):
    queryset = models.Book.objects.filter(is_delete=False)
    serializer_class = serializers.BookModelSerializer

# 视图集..set
"""
(1)优先继承ViewSetMixin 类 再继承一个视图类(GenericViewSet 和APIView)
(2)ViewSetMixin提供重写ad_view() 方法 ,继承视图集的属兔类,-匹配路由调用da_view() 必须出入对饮的映射关系as_view("get":"my_get_list")
"""
from rest_framework.viewsets import GenericViewSet  # 视图集中导入视图类
from rest_framework import mixins  # 工具类

class BookGenericViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, GenericViewSet):
    queryset = models.Book.objects.filter(is_delete=False)
    serializer_class = serializers.BookModelSerializer
    # 群查
    def my_get_list(self,request,*args, **kwargs):
        return self.list(request, *args, **kwargs)
    # 单查
    def my_get_obj(self, request,*args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

class MyRequest(APIView):
    def post(self, request, *args, **kwargs):
        request_data = request.data

        # book_ser 序列化数据对象
        book_data = serializers.BookModelSerializer(data=request_data, many=False, context={"request": request})
        # 进行数据的检验
        book_data.is_valid(raise_exception=True)
        result_data = book_data.save()
        return APIResponse(results=result_data)  # 直接封装 create() 的话要进行many = True

# 拥有就打接口:单查/群查/单增/ 单删/单整体改/单局部改
# 补充:一般肯定需要我们重写destroy 方法
"""

class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):  #  继承这个主要是让他遵循我们自己写的as_view({"get":"list",'patch':"partial_update",'put':"update","post":"create", "destroy":'destroy'})
"""
from rest_framework.viewsets import ModelViewSet

class BookModelViewSet(ModelViewSet):
    queryset = models.Book.objects.filter(is_delete=False)
    serializer_class = serializers.BookModelSerializer
    """
    as_view({"get":'list','post':'create'})
    get >>>list 群查 post >>> 新增
    as_view({'get':'retrieve','put':'update','patch':'partial_update','delete':'destroy'}
    get >>>retrieve 单查 提供pk在url  put >>> partial = False不能进单个字段的修改 而是整体字段的更新
    patch >>>> partial_update 默认partial = True,
    """
    # 一般我们删除的不是真正的数据 而是将他的bOOL 改为1 /获取是Treu
    # 除了删除需要我们自己写  因为 特会将正真的数据进行删除肯定不合理 所以我们自己写优先走我们自己的

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()  # 单删 实列化对象
        if not instance:  # 改实例对象不存在
            return APIResponse(0, '删除失败')
        instance.is_delete = True
        instance.save()
        return APIResponse(1,'删除成功')

六.serializer文件:对象  序列化 钩子函数

from rest_framework.serializers import ModelSerializer,SerializerMethodField
from rest_framework.serializers import ListSerializer
from rest_framework.exceptions import ValidationError
from . import models

# 重写我们update() 方法

# 重点将我们ListSerializer()

class BookListSerializer(ListSerializer):

    def update(self, instance, validated_data):
        print(instance,111)  # [<Book: <东游记9988>>, <Book: <西游记999>>, <Book: <南游记>>]
        print(validated_data,2222)
        # [{'name': '东游记88', 'price': Decimal('66.66')}, {'name': '西游记999',
        # 'price': Decimal('77.88')}, {'name': '南游记', 'price': Decimal('8.88')}]
        # 获取里面的所有数据
        print(self.child,12312312)
        for index, obj in enumerate(instance):
            # 获取对象的索引和下标
            self.child.update(obj,validated_data[index])
        return instance  # 返回对象

class BookModelSerializer(ModelSerializer):
    class Meta:
        model = models.Book
        # 映射
        fields = ('name','price', 'img','author_list', 'publish_name','publisher','authors')
        extra_kwargs = {
            'name':{
                'required':True,
                'min_length':3,
                'error_messages':{

                    'required':'必填字段',
                    'min_length':'不能少于3位数字'
                }
            },
            'publisher':{
                'write_only':True,
            },
            'authors':{
                'write_only': True
            },
            'img':{
                'read_only':True,

            },
            'author_list':{
                'read_only':True
            },
            'publish_name':{
                'read_only':True
            }
        }

        # patch()方法是用save()
        # 方法进行数据的更新 但是没有进行update()方法的封装 需要我们自己 重写update() 方法
        list_serializer_class = BookListSerializer
    # 局部勾子和全局钩子

    def validate_name(self,value):
        # 书名不能有'si'字符
        print(self.context,1111)
        if 'k' in value:  # ???
            raise ValidationError('该k书不能出版')
        return value

    # 全局钩子
    def validate(self, attrs):
        publisher = attrs.get('publisher')
        name = attrs.get('name')
        if models.Book.objects.filter(name=name,publisher=publisher):
            raise ValidationError({'book':'该书已经存在'})
        return attrs

七.Media 媒体文件

八. exception自定义用异常文件

from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.views import Response
from rest_framework import status
def exception_handler(exc, context):
    # drf的exception_handler做基础处理
    response = drf_exception_handler(exc, context)
    # 为空,自定义二次处理
    if response is None:
        print('%s - %s - %s' % (context['view'], context['request'].method, exc))
        return Response({
            'detail': '服务器错误'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
    return response

九.utils文件 自定义响应的数据格式 以及我们的自定义分页器

# 我们自定义from rest_framework.response import Response

class APIResponse(Response):    def __init__(self, data_status=1,data_msg='ok',                 results=None,http_status=None, headers=None,exception=False,*kwargs):  # 我们需要返回的值        # data的初始信息:        data = {            'status':data_status,            'msg':data_msg,        }        # data的响应数据体        # results 响应可能是False 0等数据 这些数据在我们设计的方法下是不合法的所以要进行过滤        if results is not None:            data['results'] = results        # 将请求后的字典内容进行更新 有则        data.update(kwargs)        super().__init__(data=data,status=http_status,headers=headers,exception=exception)

待更新........

Django rest_frameword 之项目流程的更多相关文章

  1. django搭建简单开发项目流程(一)

    1 搭建环境 sudo apt-get install python3-pip 安装pip3 sudo pip3 install virtualenv 安装虚拟环境 virtualenv -p pyt ...

  2. web理论知识--网页访问过程(附有Django的web项目访问流程)

    当我们闲暇之余想上网看看新闻,或者看个电影,通常的操作是:打开电脑.打开浏览器.输入网址.浏览页面信息.点击自己感兴趣的连接......那么有没有想过,这些网页从哪里来的?过程中计算机又做了什么事情了 ...

  3. Django 小实例S1 简易学生选课管理系统 1 项目流程梳理与数据库设计

    Django 小实例S1 简易学生选课管理系统 第1章--项目流程梳理与数据库设计 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 1 项目流程梳理 ...

  4. Django——博客项目

    博客项目 目前的目标是构建一个基于Django的前后端完整的博客系统,首先对项目流程整理如下: 1. 分析需求 1.1. 基于用户认证组件和Ajax实现登录验证 图形验证码核心代码: 模板: < ...

  5. BBS+Blog项目流程及补充知识点

    项目流程: 1. 产品需求 (1)基于用户认证组件和Ajax实现登陆验证(图片验证码) (2)基于forms组件和Ajax实现注册功能 (3)设计系统首页(文章列表渲染) (4)设计个人站点页面 (5 ...

  6. Django Rest framework实现流程

    目录 一 什么是restful架构 二 Django REST framework简介 三 Django REST framework原理 四 Django REST framework源码流程 五 ...

  7. Django运行方式及处理流程总结(转发)

    之前在网上看过一些介绍Django处理请求的流程和Django源码结构的文章,觉得了解一下这些内容对开发Django项目还是很有帮助的.所以,我按照自己的逻辑总结了一下Django项目的运行方式和对R ...

  8. iOS开发项目之一 [ 项目流程]

    项目流程 *人员配置 *客户端(iOS工程师,Android工程师) *前端 h5 *后台人员(php,java,net) *提供接口(请求地址.请求参数,请求方式,接口文档) *UI UE * 效果 ...

  9. ng机器学习视频笔记(十六) ——从图像处理谈机器学习项目流程

    ng机器学习视频笔记(十六) --从图像处理谈机器学习项目流程 (转载请附上本文链接--linhxx) 一.概述 这里简单讨论图像处理的机器学习过程,主要讨论的是机器学习的项目流程.采用的业务示例是O ...

随机推荐

  1. Mybatis 中在xxx.mapper书写模糊查询

    1.在mybatis中,书写sql,有时候会有一些不细心,如: <!-- 首页商品 关键字搜索--> <select id="getGoodsByLikeTitle&quo ...

  2. 【SpringBoot-创建项目】一.通过Idea创建SpringBoot项目

    一.首先我们通过Idea创建一个新项目 二.选择sdk和快速构建模板 三.填写项目基本信息 三.选择项目依赖 四.填写项目名和本地项目路径 六.完成项目创建,查看项目目录层级 最终:主要是在创建项目的 ...

  3. 多网卡情况下接收udp组播

    多网卡下接收udp组播 往往会接收失败 因为用错了网卡 例如我想要接收2网段 其他电脑出的udp组播  我电脑有有线网和wifi在window下可以这样 route add 230.0.0.1 mas ...

  4. [python] Pythonic语法笔记

    Pythonic语法笔记 __new__ 在类实例化之前执行的,也就是在init之前执行,可以为这个类写操作.接受的参数不是self而是cls.只有在new方法里返回类才会执行init操作,需要返回父 ...

  5. Go Int转string几种方式性能测试

    Go Int转string几种方式性能测试 - 贤冰的博客 - CSDN博客 https://blog.csdn.net/flyfreelyit/article/details/79701577

  6. ES6数值的拓展

    二进制和八进制表示法 ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示. 如果要将0b和0o前缀的字符串数值转为十进制,要使用Number方法 Number(' ...

  7. 阶段3 1.Mybatis_02.Mybatis入门案例_3.mybatis注解开发和编写dao实现类的方式

    注解的用法 直接创建一个新的项目 下一步直接next 然后finish即可 把之前项目01里面的代码直接复制过来 复制到我们02的注解的工程中 把01项目导入的依赖也都粘贴过来 再把测试类复制过去 复 ...

  8. cocos2dx基础篇(20) 扩展动作CCGridAction

    [3.x]     (1)去掉"CC" [CCGridAction] CCGridAction有两个子类:CCGrid3DAction.CCTiledGrid3DAction.而我 ...

  9. 分享一个linux中测试网站是否正常的shell脚本

    #! /bin/bash #Author=Harry CheckUrl() { #<==定义函数,名字为CheckUrl timeout=5 #<==定义wget访问的超时时间,超时就退出 ...

  10. CentOS7linux通过http配置共享自动创建yum源的shell脚本

    因工作需要用到,所以记录一下配置流程 环境介绍: 两台CentOS7系统 yum源服务主节点IP:192.168.1.78 从节点IP:192.168.1.79(79从78上获取yum源) 配置78节 ...