二、drf简单使用

<p>&nbsp;</p>
<h1>一、settings.py注册restframework</h1>
<pre><code class='language-python' lang='python'>&#39;&#39;&#39;
INSTALLED_APPS = [
    &#39;django.contrib.admin&#39;,
    &#39;django.contrib.auth&#39;,
    &#39;django.contrib.contenttypes&#39;,
    &#39;django.contrib.sessions&#39;,
    &#39;django.contrib.messages&#39;,
    &#39;django.contrib.staticfiles&#39;,
    &#39;app01.apps.App01Config&#39;,
    &#39;rest_framework&#39;
]

如果没有注册,则网页报错:
    TemplateDoesNotExist:rest_framework/api.html
&#39;&#39;&#39;
</code></pre>
<h1>二、drf的简单使用</h1>
<pre><code class='language-python' lang='python'>django2.2 + python3.6.8

# app01
    # models.py
        from django.db import models
        class Book(models.Model):
            nid = models.AutoField(primary_key=True)
            name = models.CharField(max_length=32)
            price = models.DecimalField(max_digits=5, decimal_places=2)
            author = models.CharField(max_length=32)
    # __init__.py
        import pymysql
        pymysql.install_as_MySQLdb()
    # urls.py
        from app01 import views
        from rest_framework.routers import DefaultRouter

        urlpatterns = []

        router = DefaultRouter()  # 可以处理视图的路由器
        router.register(&#39;book&#39;, views.BooksViewSet)  # 向路由器中注册视图集

        # 将路由器中的所以路由信息追到到django的路由列表中
        urlpatterns += router.urls
    # ser.py
        from rest_framework.serializers import ModelSerializer
        from app01.models import Book


        class BookModelSerializer(ModelSerializer):
            class Meta:
                model = Book
                fields = &quot;__all__&quot;
    # views.py
        from rest_framework.viewsets import ModelViewSet
        from .models import Book
        from .ser import BookModelSerializer


        class BooksViewSet(ModelViewSet):
            queryset = Book.objects.all()
            serializer_class = BookModelSerializer

# djangoProject
    # settings.py
        INSTALLED_APPS = [
            &#39;django.contrib.admin&#39;,
            &#39;app01.apps.App01Config&#39;,
            &#39;rest_framework&#39;,
        ]
    # urls.py
        from django.contrib import admin
        from django.urls import path, include

        urlpatterns = [
            path(&#39;admin/&#39;, admin.site.urls),
            path(&#39;book/&#39;, include(&#39;app01.urls&#39;))

        ]
</code></pre>
<h1>三、Request对象</h1>
<pre><code class='language-python' lang='python'>self.parsers = parsers or ()
self.authenticators = authenticators or ()
self.negotiator = negotiator or self._default_negotiator()
self.parser_context = parser_context
self._data = Empty
self._files = Empty
self._full_data = Empty
self._content_type = Empty
self._stream = Empty

# Empty 相当于一个字典
</code></pre>
<h2>1、_request</h2>
<pre><code class='language-python' lang='python'>&#39;&#39;&#39;
只要继承了APIView,那么最终 原生request 都会被加工成 新request,即Request对象
&#39;&#39;&#39;

# 原生request:Request对象的_request存储
self._request = request

&#39;&#39;&#39;
对于后续使用原生request方法并不影响,因为Request对象内部重写了__getattr__方法
&#39;&#39;&#39;
    def __getattr__(self, attr):
        try:
            &#39;&#39;&#39;
            如果你使用request.POST/GET/META/FILES/...
            那么最终都会返回原生request对象中对应的方法
            &#39;&#39;&#39;
            return getattr(self._request, attr)
        except AttributeError:
            
            &#39;&#39;&#39;
            如果原生request中不存在该方法,那么会继续从__getattribute__中寻找
            
            def __getattribute__(self, *args, **kwargs): 
                pass
            &#39;&#39;&#39;
            return self.__getattribute__(attr)
</code></pre>
<h2>2、request.data</h2>
<pre><code class='language-python' lang='python'>&#39;&#39;&#39;
post请求,不管传入什么编码,如urlencoded、json、form-data,
都在request.data中,以字典的形式显示
&#39;&#39;&#39;
    @property
    def data(self):
        if not _hasattr(self, &#39;_full_data&#39;):
            self._load_data_and_files()
        return self._full_data

# 判断对象中是否存在对应的属性/方法名
def _hasattr(obj, name):
    return not getattr(obj, name) is Empty
</code></pre>
<h2>3、request.query_params</h2>
<pre><code class='language-python' lang='python'>&#39;&#39;&#39;
query_params就是给原生request对象的GET方法换了个名字
&#39;&#39;&#39;
    @property
    def query_params(self):
        return self._request.GET
</code></pre>
<h1>四、Response对象</h1>
<pre><code class='language-python' lang='python'>&#39;&#39;&#39;
用于后端服务器响应前端请求,发送给前端数据
    如果是字典数据(request.data),则会以JSON格式发送给前端
        并根据如果为浏览器,则渲染成精美的HTML页面(Accept参数)
        否则为纯JSON数据

如果不适用Response,那么必须要使用JsonResponse,返回纯JSON数据
&#39;&#39;&#39;
def __init__(
    self, 
    data=None,                 # 传入发送给前端的数据,需要是一个字典
    status=None,            # 传入状态码,默认200
        # from rest_framework import status在这个路径下,它把所有使用到的状态码都定义成了常量
    template_name=None,     # 自定义API HTML模板
    headers=None,            # 设置响应头,需要一个字典
    exception=False,         # 异常
    content_type=None        # 响应编码类型(text/html、application/json)
)

常用属性:
    .data                # 未渲染的字典数据
    .status_code         # 传入数字,设置状态码
    .content            # 经由渲染后的响应数据
    

&#39;&#39;&#39;
Response会根据请求头中的Accept参数来进行对应操作(浏览器:渲染返回API HTML页面;postman:返回JSON数据)
如果请求头中不存在Accept参数,那么就会采用默认的方式来处理响应数据,我们可以通过配置修改默认响应格式:
    from rest_framework import settings 中存在设置案例
&#39;&#39;&#39;
全局配置(项目settings.py中增加):
    REST_FRAMEWORK = {
            # 设置默认响应渲染类
            &#39;DEFAULT_RENDERER_CLASSES&#39;: (      
                &#39;rest_framework.renderers.JSONRenderer&#39;,              # json渲染器
                &#39;rest_framework.renderers.BrowsableAPIRenderer&#39;,      # 浏览API渲染器
            )
        }

局部配置(在视图类中增加):
    from rest_framework.renderers import JSONRenderer
    renderer_classes=[JSONRenderer,]
</code></pre>
<p>&nbsp;</p>

 

上一篇:封装、继承和多态 3super关键字使用


下一篇:Vue组件(二)单文件组件