想了解Django---请求、响应的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于django请求响应流程图的相关问题,此外,我们还将为您介绍关于$Django调API的几种方式,djang
想了解Django--- 请求、响应的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于django请求响应流程图的相关问题,此外,我们还将为您介绍关于$ Django 调API的几种方式,django自定义错误响应、Django drf:视图层封装、ViewSetMixin、路由配置、解析器、响应器、Django 框架 day72------orm 增删改查、django 请求的生命周期、Django 框架篇(八): Django处理Ajax请求的新知识。
本文目录一览:- Django--- 请求、响应(django请求响应流程图)
- $ Django 调API的几种方式,django自定义错误响应
- Django drf:视图层封装、ViewSetMixin、路由配置、解析器、响应器
- Django 框架 day72------orm 增删改查、django 请求的生命周期
- Django 框架篇(八): Django处理Ajax请求
Django--- 请求、响应(django请求响应流程图)
Django 的请求和响应
一、客户端向服务器的请求简介
二、响应对象构造
回到顶部
一、客户端向服务器的请求简介
1.c-->s 的传参的 4 中途径
-
- 提取的 URL 的特定部分,如 / 天气 / 北京 / 2018,可以在服务器端的路由中用正则表达式截取;
- 查询字符串(查询字符串),形如 key1 = value1&key2 = value2;
- 请求体(主体)中发送的数据,比如表单数据,JSON,XML;
- 在 HTTP 报文的头(报头)中。
2. 传参途径的接受方式
1. 通过 url 地址传递参数
例如:在子路由 request_rout 中,urls 中设置 url(r''^weather/(?P<city>[a-z]+)/(?P<year>\d{4})/$'', views.weather),


def weather(request, year, city):
print(''city=%s'' % city)
print(''year=%s'' % year)
return HttpResponse(''OK'')
2. 通过查询字符串传递参数


# 演示从查询字符串中提取参数
# /query/?a=1&b=2&c=3
# flask: request.args
# dhango: request.GET -> QueryDict类的对象,类似于字典
def query_data(request):
a = request.GET.get(''a'')
b = request.GET.get(''b'')
c = request.GET.get(''c'')
c_list = request.GET.getlist(''c'') # list
print(c_list)
return HttpResponse("OK")
3. 通过请求体传递数据
3.1post 表单提交数据


# 演示获取post表单提交的数据
# /form/
# flask: request.form
# dhango: request.POST -> QueryDict类的对象,类似于字典
def form_data(request):
name = request.POST.get(''name'')
age = request.POST.get(''age'')
print(name)
print(age)
return HttpResponse(''OK'')
3.2json 数据


# 演示获取json数据
# /json/
# flask: request.json
# dhango: request.body -> QueryDict类的对象,类似于字典
def json_data(request):
req_data = request.body # 获取请求体原始数据 bytes
# 将bytes转换成str
json_str = req_data.decode()
# 将json字符转为字典
req_dict = json.loads(json_str)
# 取出年龄和名字
name = req_dict.get(''name'')
age = req_dict.get(''age'')
print(name)
print(age)
return HttpResponse(''OK'')
4. 通过请求头传递数据 (request.META)


def get_headers(request):
print(request.META[''CONTENT_TYPE''])
return HttpResponse(''OK'')


CONTENT_LENGTH - 请求正文的长度(作为字符串)。
CONTENT_TYPE - 请求正文的MIME类型。
HTTP_ACCEPT - 响应的可接受内容类型。
HTTP_ACCEPT_ENCODING - 可接受的响应编码。
HTTP_ACCEPT_LANGUAGE - 响应的可接受语言。
HTTP_HOST - 客户端发送的HTTP主机头。
HTTP_REFERER - 引用页面,如果有的话。
HTTP_USER_AGENT - 客户端的用户代理字符串。
QUERY_STRING - 查询字符串,作为单个(未解析的)字符串。
REMOTE_ADDR - 客户端的IP地址。
REMOTE_HOST - 客户端的主机名。
REMOTE_USER - Web服务器验证的用户(如果有)。
REQUEST_METHOD- 一个字符串,如"GET"或"POST"。
SERVER_NAME - 服务器的主机名。
SERVER_PORT - 服务器的端口(作为字符串)。
3.Django 中的 QueryDict 对象
1.HttpRequest 对象的属性 GET,POST 都是的 QueryDict 类型的对象,QueryDict 类型的对象用来处理同一个键带有多个值的情况
2. 得到 value 值的方法
2.1 方法得到():根据键获取值
如果一个键同时拥有多个值将获取最后一个值
如果键不存在则返回无值,可以设置默认值进行后续处理
dict.get(''键'',默认值) 可简写为 dict[''键'']
2.2 方法的 GetList():根据键获取值,值以列表返回,可以获取指定键的所有值
如果键不存在则返回空列表 [],可以设置默认值进行后续处理
dict.getlist(''键'',默认值)
二、响应对象构造
1. 返回 HttpResponse 类的对象或其子类的对象
1.1 格式
response = HttpResponse (''< 响应体>'', content_type=''< 响应数据类型 >'', status=''< 响应状态码 >'')
res_http[''name''] = ''yang''


# 演示构造响应对象
# /get_response/
def get_response(request):
res_http = HttpResponse("response_body", content_type=''text/html'',status=200)
res_http[''name''] = ''yang''
return res_http
2. 响应时返回 json 数据


# 演示响应时返回json数据
# /get_json/
# flask: jsonify
# Dhango: JsonResponse(<dict>)
def get_json(request):
res_dict = {
"name" : "yang",
"age" : 12
}
return JsonResponse(res_dict)
3. 响应时进行页面重定向


# 演示响应时进行页面重定向
# /redirect_test
# flask和django相同
# redirect(''url地址'')
def redirect_test(request):
# 重定向首页
req_url = reverse(''users:index'')
print(req_url)
return redirect(req_url)
$ Django 调API的几种方式,django自定义错误响应
django自定义错误响应
前提:settings.py
#debug为true时要配置网站的allowed_hosts域名
# 简单就为"*"
DEBUG = False
ALLOWED_HOSTS = [''127.0.0.1'']


直接templates下书写404.htm,400.html,403.html,500.html


#第一步:总的urls.py 重写handler函数,(注意要加项目app名 要写在上面)
from django.conf.urls import url
from django.contrib import admin
from app01 import views
# handler404="app01.views.erro"
# handler400="app01.views.erro"
# handler403="app01.views.erro"
# handler500="app01.views.erro"
urlpatterns = [
url(r''^admin/'', admin.site.urls),
url(r''^download/'', views.Download),#下载
url(r''^file/'', views.File.as_view()),#播放
url(r''^tes/'', views.tes),#test
url(r''^data/'', views.date),#test
]
#第二步:views.py写错误调的视图
from django.http import HttpResponseNotFound
def erro(request):
return HttpResponseNotFound("NOT FOUND!")
API调用方式
下面是python中会用到的库。
urllib2
httplib2
pycurl
requests
urllib2
#request
import requests, json
github_url = ”
data = json.dumps({‘name’:’test’, ‘description’:’some test repo’})
r = requests.post(github_url, data, auth=(‘user’, ‘*‘))
print r.json
#以上几种方式都可以调用API来执行动作,但requests这种方式代码最简洁,最清晰,建议采用。
#urllib2, urllib
import urllib2, urllib
github_url = ‘https://api.github.com/user/repos’
password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
password_manager.add_password(None, github_url, ‘user’, ‘*‘)
auth = urllib2.HTTPBasicAuthHandler(password_manager) # create an authentication handler
opener = urllib2.build_opener(auth) # create an opener with the authentication handler
urllib2.install_opener(opener) # install the opener…
request = urllib2.Request(github_url, urllib.urlencode({‘name’:’Test repo’, ‘description’: ‘Some test repository’})) # Manual encoding required
handler = urllib2.urlopen(request)
print handler.read()
#httplib2
import urllib, httplib2
github_url = ’
h = httplib2.Http(“.cache”)
h.add_credentials(“user”, “**“, ”
data = urllib.urlencode({“name”:”test”})
resp, content = h.request(github_url, “POST”, data)
print content
#pycurl
import pycurl, json
github_url = ”
user_pwd = “user:*”
data = json.dumps({“name”: “test_repo”, “description”: “Some test repo”})
c = pycurl.Curl()
c.setopt(pycurl.URL, github_url)
c.setopt(pycurl.USERPWD, user_pwd)
c.setopt(pycurl.POST, 1)
c.setopt(pycurl.POSTFIELDS, data)
c.perform()
Django drf:视图层封装、ViewSetMixin、路由配置、解析器、响应器
一、视图层封装
二、ViewSetMixin
三、路由配置
四、解析器
五、响应器
一、视图层封装
1.基本视图
写一个出版社的增删改查resfull接口
路由:
url(r''^publish/$'', views.PublishView.as_view()),
url(r''^publish/(?P<pk>\d+)/$'', views.PublishDetailView.as_view()),
视图:
class PublishSerializers(serializers.ModelSerializer):
class Meta:
model=models.Publish
fields=''__all__''
class PublishView(APIView):
def get(self, request):
publish_list = models.Publish.objects.all()
bs = PublishSerializers(publish_list, many=True)
# 序列化数据
return Response(bs.data)
def post(self, request):
# 添加一条数据
print(request.data)
bs=PublishSerializers(data=request.data)
if bs.is_valid():
bs.save() # 生成记录
return Response(bs.data)
else:
return Response(bs.errors)
class PublishDetailView(APIView):
def get(self,request,pk):
publish_obj=models.Publish.objects.filter(pk=pk).first()
bs=PublishSerializers(publish_obj,many=False)
return Response(bs.data)
def put(self,request,pk):
publish_obj = models.Publish.objects.filter(pk=pk).first()
bs=PublishSerializers(data=request.data,instance=publish_obj)
if bs.is_valid():
bs.save() # update
return Response(bs.data)
else:
return Response(bs.errors)
def delete(self,request,pk):
models.Publish.objects.filter(pk=pk).delete()
return Response("")
2.mixin类和generrice类编写视图
from rest_framework.mixins import CreateModelMixin,RetrieveModelMixin,ListModelMixin,UpdateModelMixin,DestroyModelMixin
from rest_framework.generics import GenericAPIView
class PublishView(ListModelMixin,CreateModelMixin,GenericAPIView):
queryset=models.Publish.objects.all()
serializer_class=PublishSerializers
def get(self, request):
return self.list(request)
def post(self, request):
return self.create(request)
class PublishDetailView(RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView):
queryset=models.Publish.objects.all()
serializer_class=PublishSerializers
def get(self,request,*args,**kwargs):
return self.retrieve(request,*args,**kwargs)
def put(self,request,*args,**kwargs):
return self.update(request,*args,**kwargs)
def delete(self,request,*args,**kwargs):
return self.destroy(request,*args,**kwargs)
3.使用generics 下ListCreateAPIView,RetrieveUpdateDestroyAPIView
from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView
class PublishView(ListCreateAPIView):
queryset=models.Publish.objects.all()
serializer_class=PublishSerializers
class PublishDetailView(RetrieveUpdateDestroyAPIView):
queryset=models.Publish.objects.all()
serializer_class=PublishSerializers
4.使用ModeiViewSet
路由:
url(r''^publish/$'', views.PublishView.as_view({''get'':''list'',''post'':''create''})),
url(r''^publish/(?P<pk>\d+)/$'', views.PublishView.as_view({''get'':''retrieve'',''put'':''update'',''delete'':''destroy''})),
视图:
from rest_framework.viewsets import ModelViewSet
class PublishView(ModelViewSet):
queryset=models.Publish.objects.all()
serializer_class=PublishSerializers
二、ViewSetMixin
-ViewSetMixin
# ViewSetMixin 写在前面,先找ViewSetMixin的as_view方法
# 用了ViewSetMixin ,视图类中,不需要再写get,post,delete....这些函数了,函数名可以自定义
# 而且这个视图类,可以响应多条路由
-使用:
-urls.py中
url(r''^publishs/'', views.PublishView.as_view({''get'': ''aaa'',''post'':''ddd''})),
url(r''^bbb/'', views.PublishView.as_view({''get'': ''bbb'',''post'':''ccc''})),
-视图类中:
class PublishView(ViewSetMixin,APIView):
def aaa(self,request):
return Response({''status'':100})
def bbb(self,request):
return Response({''bb'': "bbb"})
三、路由控制器
1.自定义路由(原生方式)
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r''^books/$'', views.BookView.as_view()),
url(r''^books/(?P<pk>\d+)$'', views.BookDetailView.as_view()),
]
class BookView(APIView):
def get(self, request):
book_list = models.Book.objects.all()
bs = BookSerializers(book_list, many=True)
return Response(bs.data)
def post(self, request):
# 添加一条数据
print(request.data)
bs=BookSerializers(data=request.data)
if bs.is_valid():
bs.save() # 生成记录
return Response(bs.data)
else:
return Response(bs.errors)
class BookDetailView(APIView):
def get(self,request,pk):
book_obj=models.Book.objects.filter(pk=pk).first()
bs=BookSerializers(book_obj,many=False)
return Response(bs.data)
def put(self,request,pk):
book_obj = models.Book.objects.filter(pk=pk).first()
bs=BookSerializers(data=request.data,instance=book_obj)
if bs.is_valid():
bs.save() # update
return Response(bs.data)
else:
return Response(bs.errors)
def delete(self,request,pk):
models.Book.objects.filter(pk=pk).delete()
return Response(""
2.半自动路由(视图类继承ModeViewSet)
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r''^publish/$'', views.PublishView.as_view({''get'':''list'',''post'':''create''})),
url(r''^publish/(?P<pk>\d+)/$'', views.PublishView.as_view({''get'':''retrieve'',''put'':''update'',''delete'':''destroy''})),
]
from rest_framework.viewsets import ModelViewSet
class PublishView(ModelViewSet):
queryset=models.Publish.objects.all()
serializer_class=PublishSerializers
3.全自动路由(自动生成路由)
from django.conf.urls import url,include
from app01 import views
from rest_framework import routers
router=routers.DefaultRouter()
# 两个参数,一个是匹配的路由,一个是视图中写的CBV的类
router.register(''publish'',views.PublishView)
urlpatterns = [
# http://127.0.0.1:8000/publish/format=json(渲染器通过这个判断,返回渲染的页面)
# url(r''^publish/'', views.PublishView.as_view({''get'':''list'',''post'':''create''})),
# http://127.0.0.1:8000/publish.json(渲染器通过这个判断,返回渲染的页面)
# url(r''^publish\.(?P<format>\w+)$'', views.PublishView.as_view({''get'':''list'',''post'':''create''})),
# 可以用 以下方式访问
# 1 http://127.0.0.1:8000/publish/
# 2 http://127.0.0.1:8000/publish.json
# 3 http://127.0.0.1:8000/publish/3
# 4 http://127.0.0.1:8000/publish/3.json
url(r'''',include(router.urls))
]
from rest_framework.viewsets import ModelViewSet
class PublishView(ModelViewSet):
queryset=models.Publish.objects.all()
serializer_class=PublishSerializers
# 小结:
-传统的url配置
url(r''^books/$'', views.BookView.as_view()),
url(r''^books/(?P<pk>\d+)$'', views.BookDetailView.as_view()),
-半自动
url(r''^publish/$'', views.PublishView.as_view({''get'':''list'',''post'':''create''})),
url(r''^publish/(?P<pk>\d+)/$'', views.PublishView.as_view({''get'':''retrieve'',''put'':''update'',''delete'':''destroy''})),
-全自动(了解)
-能自动生成多条路由
四、解析器
1.解析器的作用
根据请求头content-type选择对应的解析器队请求体内容进行处理
有appliction/json,x-www-form-urlencoded,form-data等格式
2.全局使用解析器
setting里
REST_FRAMEWORK = {
''DEFAULT_PARSER_CLASSES'':[
''rest_framework.parsers.JSONParser''
''rest_framework.parsers.FormParser''
''rest_framework.parsers.MultiPartParser''
]
}
路由:
urlpatterns = [
url(r''test/'', TestView.as_view()),
]
视图函数:
from rest_framework.views import APIView
from rest_framework.response import Response
class TestView(APIView):
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response(''POST请求,响应内容'')
def put(self, request, *args, **kwargs):
return Response(''PUT请求,响应内容'')
3.局部使用解析器
a.仅处理请求头content-type为appliction/json请求体
from django.conf.urls import url, include
from web.views.s5_parser import TestView
urlpatterns = [
url(r''test/'', TestView.as_view(), name=''test''),
]
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import JSONParser
class TestView(APIView):
parser_classes = [JSONParser, ]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response(''POST请求,响应内容'')
def put(self, request, *args, **kwargs):
return Response(''PUT请求,响应内容'')
b.仅处理请求头content-type为appliction/x-www-from-urlencoded的请求体
from django.conf.urls import url, include
from web.views import TestView
urlpatterns = [
url(r''test/'', TestView.as_view(), name=''test''),
]
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import FormParser
class TestView(APIView):
parser_classes = [FormParser, ]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response(''POST请求,响应内容'')
def put(self, request, *args, **kwargs):
return Response(''PUT请求,响应内容'')
c.仅仅处理请求头content-type为multipart/form-data的请求体
from django.conf.urls import url, include
from web.views import TestView
urlpatterns = [
url(r''test/'', TestView.as_view(), name=''test''),
]
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import MultiPartParser
class TestView(APIView):
parser_classes = [MultiPartParser, ]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response(''POST请求,响应内容'')
def put(self, request, *args, **kwargs):
return Response(''PUT请求,响应内容'')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8000/test/" method="post" enctype="multipart/form-data">
<input type="text" name="user" />
<input type="file" name="img">
<input type="submit" value="提交">
</form>
</body>
</html>
d.仅上传文件
from django.conf.urls import url, include
from web.views import TestView
urlpatterns = [
url(r''test/(?P<filename>[^/]+)'', TestView.as_view(), name=''test''),
]
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import FileUploadParser
class TestView(APIView):
parser_classes = [FileUploadParser, ]
def post(self, request, filename, *args, **kwargs):
print(filename)
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response(''POST请求,响应内容'')
def put(self, request, *args, **kwargs):
return Response(''PUT请求,响应内容'')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8000/test/f1.numbers" method="post" enctype="multipart/form-data">
<input type="text" name="user" />
<input type="file" name="img">
<input type="submit" value="提交">
</form>
</body>
</html>
e.同时多个Parser
当同时使用多个parser时,rest_framework会根据请求头content-type自动进行比对,并使用对应parser
from django.conf.urls import url, include
from web.views import TestView
urlpatterns = [
url(r''test/'', TestView.as_view(), name=''test''),
]
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
class TestView(APIView):
parser_classes = [JSONParser, FormParser, MultiPartParser, ]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response(''POST请求,响应内容'')
def put(self, request, *args, **kwargs):
return Response(''PUT请求,响应内容'')
4.源码分析
1 在调用request.data时,才进行解析,由此入手
@property
def data(self):
if not _hasattr(self, ''_full_data''):
self._load_data_and_files()
return self._full_data
2 查看self._load_data_and_files()方法---->self._data, self._files = self._parse()
def _parse(self):
#用户请求头里content_type的值
media_type = self.content_type
#self.parsers 就是用户配置的parser_classes = [FileUploadParser,FormParser ]
#self里就有content_type,传入此函数
parser = self.negotiator.select_parser(self, self.parsers)
3 查看self.negotiator.select_parser(self, self.parsers)
def select_parser(self, request, parsers):
#同过media_type和request.content_type比较,来返回解析器,然后调用解析器的解析方法
#每个解析器都有media_type = ''multipart/form-data''属性
for parser in parsers:
if media_type_matches(parser.media_type, request.content_type):
return parser
return None
4 最终调用parser的解析方法来解析parsed = parser.parse(stream, media_type, self.parser_context)
1 Request实例化,parsers=self.get_parsers()
Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
2 get_parsers方法,循环实例化出self.parser_classes中类对象
def get_parsers(self):
return [parser() for parser in self.parser_classes]
3 self.parser_classes 先从类本身找,找不到去父类找即APIVIew 中的
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
4 api_settings是一个对象,对象里找DEFAULT_PARSER_CLASSES属性,找不到,会到getattr方法
def __getattr__(self, attr):
if attr not in self.defaults:
raise AttributeError("Invalid API setting: ''%s''" % attr)
try:
#调用self.user_settings方法,返回一个字典,字典再取attr属性
val = self.user_settings[attr]
except KeyError:
# Fall back to defaults
val = self.defaults[attr]
# Coerce import strings into classes
if attr in self.import_strings:
val = perform_import(val, attr)
# Cache the result
self._cached_attrs.add(attr)
setattr(self, attr, val)
return val
5 user_settings方法 ,通过反射去setting配置文件里找REST_FRAMEWORK属性,找不到,返回空字典
@property
def user_settings(self):
if not hasattr(self, ''_user_settings''):
self._user_settings = getattr(settings, ''REST_FRAMEWORK'', {})
return self._user_settings
五、响应器
1.作用
根据用户请求url或用户可接受的类型,筛选出合适的渲染组件
用户请求URL:
http://127.0.0.1:8000/test/?format=json
http://127.0.0.1:8000/test.json
2.内置渲染器
显示json格式:JSONRenderer
访问URL:
- http://127.0.0.1:8000/test/?format=json
- http://127.0.0.1:8000/test.json
- http://127.0.0.1:8000/test/
默认显示格式:BrowsableAPIRenderer(可以修改它的html文件)
访问URL:
- http://127.0.0.1:8000/test/?format=api
- http://127.0.0.1:8000/test.api
- http://127.0.0.1:8000/test/
表格方式:AdminRenderer
访问URL:
- http://127.0.0.1:8000/test/?format=admin
- http://127.0.0.1:8000/test.admin
- http://127.0.0.1:8000/test/
form表单方式:HTMLFormRenderer
访问URL:
- http://127.0.0.1:8000/test/?format=form
- http://127.0.0.1:8000/test.form
- http://127.0.0.1:8000/test/
3.局部使用
from rest_framework.renderers import HTMLFormRenderer,BrowsableAPIRenderer
class BookDetailView(APIView):
renderer_classes = [HTMLFormRenderer,BrowsableAPIRenderer ]
def get(self,request,pk):
book_obj=models.Book.objects.filter(pk=pk).first()
bs=BookSerializers(book_obj,many=False)
return Response(bs.data)
def put(self,request,pk):
book_obj = models.Book.objects.filter(pk=pk).first()
bs=BookSerializers(data=request.data,instance=book_obj)
if bs.is_valid():
bs.save() # update
return Response(bs.data)
else:
return Response(bs.errors)
def delete(self,request,pk):
models.Book.objects.filter(pk=pk).delete()
return Response("")
4.全局使用
setting里配置:
REST_FRAMEWORK = {
''DEFAULT_RENDERER_CLASSES'':[''rest_framework.renderers.JSONRenderer'']
}
5.自定义显示模板
from rest_framework.renderers import TemplateHTMLRenderer
class BookDetailView(APIView):
renderer_classes = [TemplateHTMLRenderer]
def get(self,request,pk):
book_obj=models.Book.objects.filter(pk=pk).first()
bs=BookSerializers(book_obj,many=False)
return Response(bs.data,template_name=''aa.html'')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ title }}
{{ publishDate }}
</body>
</html>
Django 框架 day72------orm 增删改查、django 请求的生命周期
一、orm 介绍
1.orm 的使用
(1)tools--->Run manage.py Task
makemigrations(记录数据库的修改记录)
migrate(把数据同步到数据库)
(2)python3 manage.py makemigrations
2.orm 能做的事情与不能做的事情
(1) 能创建数据表,新增和删除字段
(2) 不能创建数据库
3.orm 增加字段(注意:数据库迁移命令两条,后来增加的字段需要有默认值)
4. 删除字段
注释掉字段,执行数据库迁移的命令
5. 修改字段
直接修改字段,执行数据库迁移命令
6.user 的增删改查 ------ 重点
1 单表查询所有用户:models.User.objects.all()
得到的是 queryset对象(当成列表),列表里面,一个一个的对象[user1,user2]
2 render(request, ''userlist.html'', {''user_list'': ret})
3 模板里: {% for user in user_list %}
#要循环的内容
{{user.name}}
{% endfor%}
4 get请求携带参数:
http://127.0.0.1:8000/deleteuser/?id=1
后台取值:request.GET.get(''id'')
request.GET[''id'']
5 orm删除记录 models.User.objects.filter(id=id).delete()
返回值:影响的行数
6 前台post提交的数据取值:name=request.POST.get(''name'')
7 orm保存:
两种方式:
1 user=models.User.objects.create(name=name,password=pwd,address=addr)
2 user=models.User(name=name,password=pwd,address=addr)
user.save()
8 orm查询单条数据:user=models.User.objects.filter(id=id).first()
9 orm的修改 models.User.objects.filter(id=id).update(name=name,password=pwd,address=addr)
7.django的请求生命周期
用户浏览器--->web服务器--->中间件--->url路由层--->视图层拿到数据--->模板层拿到一个模板,通过数据渲染到模板上--->原路返回
Django 框架篇(八): Django处理Ajax请求
一. Ajax 简介:
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
- 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
- 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
详情请见: 前端之jQuery 中的Ajax交互方式
二. JSON字符串介绍:
定义:
- JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
- JSON 是轻量级的文本数据交换格式
- JSON 独立于语言 *
- JSON 具有自我描述性,更易理解
javascript中 对象 转化成json字符串的方法:
JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。
JSON.stringify({"name":"alex"})
javascript中 json字符串 转化成 js对象的方法:
JSON.parse(): 用于将一个 JSON 字符串转换为 JavaScript 对象
JSON.parse(''{"name":"alex"}'');
三. Django处理Ajax的post请求:
正常的Django处理form表单中的post请求:
因为django中中间件的保护机制, 需要对请求中的cookie和表单中的 "csrfmiddlewaretoken" 进行匹配,所以需要在页面中加上 {% csrf_token %} 标签来进行验证;
而Ajax中的请求不是通过form表单进行发送的, 所以, 就需要想办法 获取到 "csrfmiddlewaretoken" 所对应的值, 一起发过去.
如何获取 "csrfmiddlewaretoken" 所对应的值
1. 通过jQuery的属性选择器获取:
在这里还需要在html中 加入{% csrf_token %} 标签

$.ajax({
url: "/cookie_ajax/",
type: "POST",
data: {
"username": "Q1mi",
"password": 123456, "csrfmiddlewaretoken": $("[name = ''csrfmiddlewaretoken'']").val() // 使用jQuery取出csrfmiddlewaretoken的值,拼接到data中 }, success: function (data) { console.log(data); } })

2. 通过获取cookie中的 ''csrftoken'' 在请求头中添加 "X-CSRFToken" 对应的键值对:

$.ajax({
url: "/cookie_ajax/",
type: "POST",
headers: {"X-CSRFToken": $.cookie(''csrftoken'')}, // 从Cookie取csrftoken,并设置到请求头中 data: {"username": "Q1mi", "password": 123456}, success: function (data) { console.log(data); } })

3. 自己从新写一个获取cookie的js方法:

function getCookie(name) {
var cookieValue = null; if (document.cookie && document.cookie !== '''') { var cookies = document.cookie.split('';''); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + ''='')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrftoken = getCookie(''csrftoken''); // 上面是 自定义的 获取的 csrftoken ------------------------------------------------------------------------------------- // 下面是更改一下 ajax的初始化配置, 让每次的 ajax请求都提前添加 cookie的请求头 function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } });

注意:
以上 方法都必须保证在页面加载的时候 cookie存在csrftoken的值.
如果 html模板中没有包含 {% csrf_token %} 标签的话, django将不会设置 cookie;
此时可以用 django.views.decorators.csrf 包中的 ensure_csrf_cookie 函数来进行装饰被访问的 视图函数 示例:
from django.views.decorators.csrf import ensure_csrf_cookie
@ensure_csrf_cookie
def login(request):
pass
官方有关csrf的解释文档
示例: 利用ajax上传文件:

// 上传文件示例
$("#b3").click(function () {
var formData = new FormData(); formData.append("csrfmiddlewaretoken", $("[name=''csrfmiddlewaretoken'']").val()); formData.append("f1", $("#f1")[0].files[0]); $.ajax({ url: "/upload/", type: "POST", processData: false, // 告诉jQuery不要去处理发送的数据 contentType: false, // 告诉jQuery不要去设置Content-Type请求头 data: formData, success:function (data) { console.log(data) } }) })

关于Django--- 请求、响应和django请求响应流程图的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于$ Django 调API的几种方式,django自定义错误响应、Django drf:视图层封装、ViewSetMixin、路由配置、解析器、响应器、Django 框架 day72------orm 增删改查、django 请求的生命周期、Django 框架篇(八): Django处理Ajax请求的相关信息,请在本站寻找。
本文标签: