demo

# 获取课程的视图
from django.shortcuts import HttpResponse

from rest_framework.views import APIView
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer

from api import models
from api.serializers.course import CourseSerializer  # 导入序列化插件
import json

class CourseView(APIView):
    renderer_classes = [JSONRenderer,BrowsableAPIRenderer]   # 渲染器

    ret = {'code':1000,'data':None,'error':None}

    def get(self,request,*args,**kwargs):
        # course_list是一个queryset = [obj,obj]  QuerySet,是django的类型
        course_list = models.DegreeCourse.objects.all().only('id','name')
        ser= CourseSerializer(instance=course_list,many=True)   # 取到序列化器要实例化
        # querydict 是django的   OrderedDict  是Python的
        print(ser.data,type(ser.data))
        # 所以json.dumps就可以对数据进行序列化
        print(json.dumps(ser.data))
        # [{"id": 1, "name": "21u5929u5b66u4f1apythonu57fau7840"}, {"id": 3, "name": "javau9879u76ee"}, {"id": 2, "name": "pythonu67b6u6784"}]
        return HttpResponse("6666")

当打印数据出现乱码,可添加ensure_ascii=False

注意点

querydict 是django的   OrderedDict  是Python的
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer  # 渲染器 +   BrowsableAPIRenderer  是用框架提供的模板

分页

源码

关于ser = CourseDetailSerializer(instance=obj,many=False)的many=false执行了什么内容?

从ModelSerializer 找到 BaseSerializer
class BaseSerializer(Field):

    def __init__(self, instance=None, data=empty, **kwargs):
        self.instance = instance
        if data is not empty:
            self.initial_data = data
        self.partial = kwargs.pop('partial', False)
        self._context = kwargs.pop('context', {})
        kwargs.pop('many', None)
        super(BaseSerializer, self).__init__(**kwargs)

    def __new__(cls, *args, **kwargs):
        # We override this method in order to automagically create
        # `ListSerializer` classes instead when `many=True` is set.
        # 如果没有mang即为False
        if kwargs.pop('many', False):
            return cls.many_init(*args, **kwargs)  # ---> True
        return super(BaseSerializer, cls).__new__(cls, *args, **kwargs)  # --> False



            # obj = CourseDetailSerializer.__new__
            # obj.__init__
            # many=False,
            #       obj= CourseDetailSerializer的对象来进行序列化数据。
            #       obj.__init__
            # many=True
            #       obj = ListSerializer() 的对象来进行序列化数据。
            #       obj.__init__ 

认证

配置版本

源码解析

当把url(r'^(?P<version>w+)')写成匹配任意版本型号

1:导入这个看关于版本的源码流程
from rest_framework.versioning import URLPathVersioning    # 关于url版本

2:查看是否为规定版本
class URLPathVersioning(BaseVersioning):
    invalid_version_message = _('Invalid version in URL path.')
    # version --> 版本
    def determine_version(self, request, *args, **kwargs):
        version = kwargs.get(self.version_param, self.default_version)
        if not self.is_allowed_version(version):  #  判断是否为规定的版本
            raise exceptions.NotFound(self.invalid_version_message)
        return version
3
    def is_allowed_version(self, version):
        if not self.allowed_versions: ----> 当有的返回True
            return True
        return ((version is not None and version == self.default_version) or
                (version in self.allowed_versions))

4:如果上没有,这里还有一层验证
class BaseVersioning(object):
    default_version = api_settings.DEFAULT_VERSION  # 默认的版本
    allowed_versions = api_settings.ALLOWED_VERSIONS 

基于url版本的配置参数(需要配置的参数)

class BaseVersioning(object):
    default_version = api_settings.DEFAULT_VERSION     # 默认的版本
    allowed_versions = api_settings.ALLOWED_VERSIONS   # 允许的版本
    version_param = api_settings.VERSION_PARAM         # 参数

将全部的api配置版本

设计url
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/(?P<version>[v1|v2]+)/', include('api.urls')),
    # url("login/$",login.LoginView.as_view())
]


配置全局文件
#     配置版本相关  基于url的版本 , 最后三个参数看源码
    'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
    'DEFAULT_VERSION':'v1',
    'ALLOWED_VERSIONS':['v1','v2'],
    'VERSION_PARAM':'version'

 

关于继承GenericAPIView的queryset

 印象深刻的事:
由于原来对于继承关系不太清楚,写接口 APIView/泛指GenericAPIView不太关注queryset
                    
没有设置渲染器:默认 [JSONRenderer,BrowsableAPIRenderer]
                    
BrowsableAPIRenderer,内部检查当前视图函数是否有 get_queryset,如有则会调用。未设置,则断言异常。

关于每个视图需要设置renderer_classes = [JSONRenderer,]

所有视图都有功能:添加到配置文件

# 设置全局配置
REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES':['rest_framework.parsers.JSONParser'],        # 解析器
    'DEFAULT_RENDERER_CLASSES':['rest_framework.renderers.JSONRenderer'],   # 渲染器

.html

    url(r'^course/(?P<pk>d+).html$',course.CourseView.as_view({'get':'retrive'})),

加.html可以加重类似百度爬虫收录的显示权重

面试

django的orm操作怎么设置id不等于5

--->exclude排除

 # 排除专题课
course_list = models.DegreeCourse.objects.all().only('id','name').exclude(course_type=3).order_by('-id')
        # course_list是一个queryset = [obj,obj]  QuerySet,是django的类型
        # 获取url参数course_type
        # course_type = request.query_params.get("course_type")
        # 过滤专题课
        # course_list = models.DegreeCourse.objects.all().only('id','name').filter(course_type=course_type).order_by('-id')

        # 有或的要求-->多个过滤条件 getlist取多个值
        course_type = request.query_params.getlist('course_type')
        course_list = models.Course.objects.all().filter(course_type__in=course_type).only('id','name').order_by(
            '-id')

source

- 简单:fk/o2o/choice   -> source
- 复杂:m2m/gfk         -> SerializerMethodField

class CourseSerializer(ModelSerializer):
    category = serializers.CharField(source='sub_category.name') # 一对多的
    xx = serializers.CharField(source='get_course_type_display')  # 取课程类型
    price_policy = serializers.SerializerMethodField()
    class Meta:
        model = models.Course
        fields = ['id', 'name','category','xx','price_policy']

    def get_price_policy(self, obj):
        price_policy_list = obj.degreecourse_price_policy.all()
        return [{'id': row.id, 'price': row.price, 'period': row.get_valid_period_display()} for row in price_policy_list]

 ajax

application/json作为请求content-type,告诉服务器请求的主题内容是json格式的字符串,
服务器端会对json字符串进行解析,这种方式的好处就是前端人员不需要关心数据结构的复杂度,
只要是标准的json格式就能提交成功

设置全局的请求头

//  在main.js
//  设置全局的请求头
axios.defaults.headers['Content-Type'] = 'application/json'
原文地址:https://www.cnblogs.com/jassin-du/p/8858359.html