Django基础之(十)DRF

发布时间:2019-10-08 20:15:33编辑:auto阅读(1700)

    DRF基础之二

    简介

    官方文档

    Requirements

    REST framework requires the following:

    • Python (2.7, 3.4, 3.5, 3.6, 3.7)
    • Django (1.11, 2.0, 2.1)
    • The following packages are optional:

    coreapi (1.32.0+) - Schema generation support.
    Markdown (2.1.0+) - Markdown support for the browsable API.
    django-filter (1.0.1+) - Filtering support.
    django-crispy-forms - Improved HTML display for filtering.
    django-guardian (1.1.1+) - Object level permissions support

    安装与配置

    • 安装
    pip3 install djangorestframework
    pip3 install markdown # Markdown support for the browsable API.
    pip3 install django-filter # Filtering support
    • 配置
    django-admin startproject devops
    vim devops/settings.py
    INSTALLED_APPS = (
           ...
            'rest_framework‘
        )
    # 重新创建数据库day4,并配置vim devops/settings.py
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'day4',
            'USER': 'root',
            'PASSWORD': '123456',
            'HOST': 'localhost',
            'PORT': 3306,
            'OPTIONS': {
                'init_command': 'SET default_storage_engine=INNODB;',
            },
        }
    }
    • 新建一个idc的app
    mkdir apps
    django-admin startapp idc
    mv idc apps
    touch apps/__init__.py
    • 将apps座位mainPath,并做配置
    • 加入settings.py环境变量
    import sys
    sys.path.insert(0,os.path.join(BASE_DIR,'apps'))
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'rest_framework',
        'idc.apps.IdcConfig'
    ]
    • 定义好主备路由
    - 主路由
    from django.conf.urls import url,include
    from django.contrib import admin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^',include('idc.urls'))
    ]
    
    - 项目路由
    from django.conf.urls import url,include
    from . import views
    urlpatterns = [
        url(r'idcs/$',views.idc_list)
    ]
    • 创建idc/models.py
    from django.db import models
    
    class Idc(models.Model):
        name = models.CharField("IDC名称",max_length=128,blank=False,null=True)
        address = models.CharField("IDC地址",max_length=200,default="")
        phone = models.CharField("IDC联系电话",max_length=20,null=True)
        email = models.EmailField("IDC邮箱")
    
        def __str__(self):
            return self.name
    
        class Meta:
            db_table = "idc"
    • 创建idc/serializers.py
    from rest_framework import serializers
    from .models import Idc
    class IdcSerializer(serializers.Serializer):
        id = serializers.IntegerField(read_only=True)
        name = serializers.CharField()
        address = serializers.CharField()
        phone = serializers.CharField()
        email = serializers.EmailField()
    • 数据库同步&生成数据
    (venv3) [vagrant@localhost devops]$ python3 manage.py makemigrations
    (venv3) [vagrant@localhost devops]$ python3 manage.py migrate
    (venv3) [vagrant@localhost devops]$ python3 manage.py shell
    In [1]: from idc.models import Idc                                                      
    In [2]: idc = Idc()                                                                     
    In [3]: idc.name = "北京机房"                                                           
    In [4]: idc.address = "北京市酒仙桥"                                                    
    In [5]: idc.phone = "123990131"                                                         
    In [6]: idc.email = "beijing@idc.com"                                                   
    In [7]: idc.save()                                                                      
    In [8]: idc                                                                             
    Out[8]: <Idc: 北京机房>
    In [10]: data = {"name":"上海机房","address":"上海","phone":"90909931","email":"shanghai@idc.com"}                           In [11]:                                                                                
    In [11]: data                                                                           
    Out[11]: 
    {'name': '上海机房',
     'address': '上海',
     'phone': '90909931',
     'email': 'shanghai@idc.com'}
    In [12]: idc = Idc(**data)                                                              
    In [13]: idc.save() 
    In [14]: Idc.objects.all()                                                              
    Out[14]: <QuerySet [<Idc: 北京机房>, <Idc: 上海机房>]>
    In [15]: idc                                                                            
    Out[15]: <Idc: 上海机房>
    In [16]: from idc.serializers import IdcSerializer                                      
    In [17]: serializer = IdcSerializer(idc)                                                
    In [18]: serializer                                                                     
    Out[18]: 
    IdcSerializer(<Idc: 上海机房>):
        id = IntegerField()
        name = CharField()
        address = CharField()
        phone = CharField()
        email = EmailField()
    In [19]: serializer.data                                                                
    Out[19]: {'id': 2, 'name': '上海机房', 'address': '上海', 'phone': '90909931', 'email': 'shanghai@idc.com'}
    • 会出错的地方
    In [21]: import json   
    In [22]: json.dumps(serializer.data)                                                         
    Out[22]: '{"id": 2, "name": "\\u4e0a\\u6d77\\u673a\\u623f", "address": "\\u4e0a\\u6d77", "phone": "90909931", "email": "shanghai@idc.com"}'
    In [23]: from rest_framework.renderers import JSONRenderer               
    In [24]: content = JSONRenderer().render(serializer.data)                     
    In [25]: content                     #获取到浏览器的数据
    Out[25]: b'{"id":2,"name":"\xe4\xb8\x8a\xe6\xb5\xb7\xe6\x9c\xba\xe6\x88\xbf","address":"\xe4\xb8\x8a\xe6\xb5\xb7","phone":"90909931","email":"shanghai@idc.com"}'
    In [26]: from django.utils.six import BytesIO                                                                                                                                                                                                    
    In [27]: stream = BytesIO(content)               #将获取的数据转换成一个流                                                                                                                                                                                        
    In [28]: from rest_framework.parsers import JSONParser                                                                                                                                                                                           
    In [29]: data = JSONParser().parse(stream)          #将数据转换成dict                                                                     
    In [30]: data                                                                                                                                                                                                                                    
    Out[30]: 
    {'id': 2,
     'name': '上海机房',
     'address': '上海',
     'phone': '90909931',
     'email': 'shanghai@idc.com'}
    • 新创建数据并测试
    from rest_framework import serializers
    from .models import Idc
    
    class IdcSerializer(serializers.Serializer):
        id = serializers.IntegerField(read_only=True)
        name = serializers.CharField()
        address = serializers.CharField()
        phone = serializers.CharField()
        email = serializers.EmailField()
        def create(self, validated_data):
            return Idc.objects.create(**validated_data)
    

    测试:

    In [1]: data = {"name":"上海机房","address":"上海","phone":"90909931","email":"shanghai@idc.com"}                                                                                                                                           
    In [2]: data                                                                                                                                                                                                                                     
    Out[2]: 
    {'name': '上海机房',
     'address': '上海',
     'phone': '90909931',
     'email': 'shanghai@idc.com'}
    In [3]: from idc.serializers import IdcSerializer                                                                                                                                                                                                
    In [4]: idc = IdcSerializer(data=data)                                                                                                                                                                                                           
    In [5]: idc.is_valid()                                                                                                                                                                                                                           
    Out[5]: True
    In [6]: idc.save()                                                                                                                                                                                                                               
    Out[6]: <Idc: 上海机房>
    • 处理queryset
    In [7]: from idc.models import Idc                                                                                                                                                                                                               
    In [8]: Idc.objects.all()                                                                                                                                                                                                                        
    Out[8]: <QuerySet [<Idc: 北京机房>, <Idc: 上海机房>, <Idc: 上海机房>]>
    In [9]: queryset = Idc.objects.all()                                                                                                                                                                                                             
    In [10]: IdcSerializer(queryset)    
    In [15]: ser = IdcSerializer(queryset,many=True)        #many=False是要单个数据                                                                                                                                                                           
    In [16]: ser.data                                                                                                                                                                                                                                
    Out[16]: [OrderedDict([('id', 1), ('name', '北京机房'), ('address', '北京市酒仙桥'), ('phone', '123990131'), ('email', 'beijing@idc.com')]), OrderedDict([('id', 2), ('name', '上海机房'), ('address', '上海'), ('phone', '90909931'), ('email', 'shanghai@idc.com')]), OrderedDict([('id', 3), ('name', '上海机房'), ('address', '上海'), ('phone', '90909931'), ('email', 'shanghai@idc.com')])]

    序列化模型

    model obj ==== > JSON

    反序列化模型

    http提交的数据 ==== > JSON =====> obj(model obj)

    • 创建idc/views.py
    from .models import Idc
    from .serializers import IdcSerializer
    from rest_framework.renderers import JSONRenderer
    from rest_framework.parsers import JSONParser
    from django.http import HttpResponse,JsonResponse
    
    class JSONResponse(HttpResponse):
        def __init__(self,data,**kwargs):
            kwargs.setdefault('content_type', 'application/json')
            content = JSONRenderer().render(data)
            super(JSONResponse,self).__init__(content=content,**kwargs)
    
    def idc_list(request,*args,**kwargs):
        if request.method == "GET":
            queryset = Idc.objects.all()
            serializer = IdcSerializer(queryset,many=True)
            return JSONResponse(serializer.data)
            # content = JSONRenderer().render(serializer.data)
            # return HttpResponse(content,content_type="application/json")
    
        elif request.method == "POST":
            content = JSONParser().parse(request)
            serializer = IdcSerializer(data=content)
            if serializer.is_valid():
                serializer.save()
                content = JSONRenderer().render(serializer.data)
                return HttpResponse(content, content_type="application/json")
    • 测试
    In [17]: import requests                                                                                                                                                                                                                         
    In [18]: url = "http://192.168.33.10:8080/idcs/"                                                                                                                                                                                                 
    In [19]: data = {"name":"上海机房","address":"上海","phone":"90909931","email":"shanghai@idc.com"}                                                                                                                                         
    In [20]: requests.post(url,data)                                                                                                                                                                                                                 
    Out[20]: <Response [500]>
    In [21]: r = requests.post(url,json=data)                                                                                                                                                                                                        
    In [22]: r.status_code                                                                                                                                                                                                                           
    Out[22]: 500
    In [23]: r = requests.post(url,json=data)                                                                                                                                                                                                        
    In [24]: r.status_code                                                                                                                                                                                                                           
    Out[24]: 200
    In [25]: r.content                                                                                                                                                                                                                               
    Out[25]: b'{"id":5,"name":"\xe4\xb8\x8a\xe6\xb5\xb7\xe6\x9c\xba\xe6\x88\xbf","address":"\xe4\xb8\x8a\xe6\xb5\xb7","phone":"90909931","email":"shanghai@idc.com"}'
    • 详情相关的数据

    idc/urls.py:

    from django.conf.urls import url
    from . import views
    
    urlpatterns = [
        url(r'idcs/$',views.idc_list),
        url(r'idcs/(?P<pk>[0-9]+)/$',views.idc_detail),
    ]

    views.py

    from .models import Idc
    from .serializers import IdcSerializer
    from rest_framework.renderers import JSONRenderer
    from rest_framework.parsers import JSONParser
    from django.http import HttpResponse,JsonResponse
    
    class JSONResponse(HttpResponse):
        def __init__(self,data,**kwargs):
            kwargs.setdefault('content_type', 'application/json')
            content = JSONRenderer().render(data)
            super(JSONResponse,self).__init__(content=content,**kwargs)
    
    def idc_list(request,*args,**kwargs):
        if request.method == "GET":
            queryset = Idc.objects.all()
            serializer = IdcSerializer(queryset,many=True)
            return JSONResponse(serializer.data)
            # content = JSONRenderer().render(serializer.data)
            # return HttpResponse(content,content_type="application/json")
    
        elif request.method == "POST":
            content = JSONParser().parse(request)
            serializer = IdcSerializer(data=content)
            if serializer.is_valid():
                serializer.save()
                content = JSONRenderer().render(serializer.data)
                return HttpResponse(content, content_type="application/json")
    
    def idc_detail(request,pk,*args,**kwargs):
        try:
            idc = Idc.objects.get(pk=pk)
        except Idc.DoesNotExist:
            return HttpResponse(status=404)
    
        if request.method == "GET":
            serializer = IdcSerializer(idc)
            return JSONResponse(serializer.data)
    
        elif request.method == "POST":
            content = JSONParser().parse(request)
            serializer = IdcSerializer(data=content)
            if serializer.is_valid():
                serializer.save()
                return JSONResponse(serializer.data)
    
        elif request.method == "PUT":
            content = JSONParser().parse(request)
            serializer = IdcSerializer(idc,data=content)
            if serializer.is_valid():
                serializer.save()
                return JSONResponse(serializer.data)
    
        elif request.method == "DELETE":
            idc.delete()
            return HttpResponse(status=204)

    测试:

    In [1]: import requests                                                                 
    In [2]: url = "http://192.168.33.10:8080/idcs/2/"                                       
    In [3]: requests.get(url)                                                               
    Out[3]: <Response [200]>
    In [4]: requests.get(url).content                                                       
    Out[4]: b'{"id":2,"name":"\xe4\xb8\x8a\xe6\xb5\xb7\xe6\x9c\xba\xe6\x88\xbf","address":"\xe4\xb8\x8a\xe6\xb5\xb7","phone":"90909931","email":"shanghai@idc.com"}'
    In [5]: requests.delete(url)                                                            
    Out[5]: <Response [204]>
    [vagrant@localhost ~]$ curl -s -X PUT -d '{"name":"wanghui"}' http://192.168.33.10:8080/idcs/1/     #更新操作
    {"id":1,"name":"wanghui","address":"北京市酒仙桥","phone":"123990131","email":"beijing@idc.com"}[vagrant@localhost ~]$ 

关键字