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 ~]$