导读:本篇文章首席CTO笔记来给大家介绍有关前端如何调用Django后端的相关内容,希望对大家有所帮助,一起来看看吧。
Django接受前端数据的几种方法
字符型
字符型的数据相对好获取,前端传递的方法如下:
sendData = { \"exporttype\": exporttype,
\"bugids\": bugids,
\"test\": JSON.stringify({\"test\": \"test\"})
};
在Django的后端只要使用exporttype = request.GET.get(\"exporttype\")
就能正常的获取到这个数据了。
注意: 在Python2.7中数据是unicode编码的,如果要使用,有时候需要进行转str
结果示例:
Excle type \'unicode\'
数组型
获取数组型的数据如果使用获取字符串的数据的方法,打出的结果是None。我们要使用这个方法:
bugids = request.GET.getlist(\"bugids[]\")
这样获取的数据就是数组类型。
注意: 获取的数组中的元素是unicode编码的,在某些时候使用需要转编码
结果示例:
•传递的url
[14/Jul/2016 11:00:41]\"GET /testtools/exportbug/?exporttype=Exclebugids%5B%5D=102bugids%5B%5D=101bugids%5B%5D
•获取的数据
[u\'102\', u\'101\', u\'100\', u\'99\', u\'98\', u\'97\', u\'96\', u\'95\', u\'94\', u\'93\', u\'92\', u\'91\', u\'90\', u\'89\', u\'88\', u\'87\'
字典型
字典型数据其实可以当成字符串数据来处理,获取到对应字符串后使用JSON模块做一下格式化就行了。
对于前端来说,传递字典型的数据就是传递JSON数据,所以使用的方法是:
\"test\": JSON.stringify({\"test\": \"test\"})
结果示例:
{\"test\":\"test\"} type \'unicode\'
相关源码
•Get方法
Get方法是wsgi里面的一个方法。
def GET(self):
# The WSGI spec says \'QUERY_STRING\' may be absent.
raw_query_string = get_bytes_from_wsgi(self.environ, \'QUERY_STRING\', \'\')
return http.QueryDict(raw_query_string, encoding=self._encoding)
最终返回的是一个http.QueryDict(raw_query_string, encoding=self._encoding)http的原始数据,而QueryDict继承于MultiValueDict ,所以我们直接看MultiValueDict就好了。
•MultiValueDict
其实源码看起来并不难。
def get(self, key, default=None):
\"\"\"
Returns the last data value for the passed key. If key doesn\'t exist
or value is an empty list, then default is returned.
\"\"\"
try:
val = self[key]
except KeyError:
return default
if val == []:
return default
return val
def getlist(self, key, default=None):
\"\"\"
Returns the list of values for the passed key. If key doesn\'t exist,
then a default value is returned.
\"\"\"
try:
return super(MultiValueDict, self).__getitem__(key)
except KeyError:
if default is None:
return []
return default
def __getitem__(self, key):
\"\"\"
Returns the last data value for this key, or [] if it\'s an empty list;
raises KeyError if not found.
\"\"\"
try:
list_ = super(MultiValueDict, self).__getitem__(key)
except KeyError:
raise MultiValueDictKeyError(repr(key))
try:
return list_[-1]
except IndexError:
return []
要调试一个用java写的后端,django写的前端的web应用应该怎么调试
在以前,你选择Pythonweb架构会受制于可用的web服务器,反之亦然。如果架构和服务器可以协同工作,那你就走运了:
但你有可能面对(或者曾有过)下面的问题,当要把一个服务器和一个架构结合起来是发现他们不是被设计成协同工作的:
基本上你只能用可以一起运行的而非你想要使用的。
那么,你怎么可以不修改服务器和架构代码而确保可以在多个架构下运行web服务器呢?答案就是PythonWebServerGatewayInterface(或简称WSGI,读作“wizgy”)。
WSGI允许开发者将选择web框架和web服务器分开。现在你可以混合匹配web服务器和web框架,选择一个适合你需要的配对。比如,你可以在Gunicorn或者Nginx/uWSGI或者Waitress上运行Django,Flask,或Pyramid。真正的混合匹配,得益于WSGI同时支持服务器和架构:
WSGI是第一篇和这篇开头又重复问道问题的答案。你的web服务器必须具备WSGI接口,所有的现代PythonWeb框架都已具备WSGI接口,它让你不对代码作修改就能使服务器和特点的web框架协同工作。
现在你知道WSGI由web服务器支持,而web框架允许你选择适合自己的配对,但它同样对于服务器和框架开发者提供便利使他们可以专注于自己偏爱的领域和专长而不至于相互牵制。其他语言也有类似接口:java有ServletAPI,Ruby有Rack。
说这么多了,你肯定在喊,给我看代码!好吧,看看这个极简的WSGI服务器实现:
#TestedwithPython2.7.9,LinuxMacOSX
importsocket
importStringIO
importsys
classWSGIServer(object):
address_family=socket.AF_INET
socket_type=socket.SOCK_STREAM
request_queue_size=1
def__init__(self,server_address):
#Createalisteningsocket
self.listen_socket=listen_socket=socket.socket(
self.address_family,
self.socket_type
)
#Allowtoreusethesameaddress
listen_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
#Bind
listen_socket.bind(server_address)
#Activate
listen_socket.listen(self.request_queue_size)
#Getserverhostnameandport
host,port=self.listen_socket.getsockname()[:2]
self.server_name=socket.getfqdn(host)
self.server_port=port
#ReturnheaderssetbyWebframework/Webapplication
self.headers_set=[]
defset_app(self,application):
self.application=application
defserve_forever(self):
listen_socket=self.listen_socket
whileTrue:
#Newclientconnection
self.client_connection,client_address=listen_socket.accept()
#Handleonerequestandclosetheclientconnection.Then
#loopovertowaitforanotherclientconnection
self.handle_one_request()
defhandle_one_request(self):
self.request_data=request_data=self.client_connection.recv(1024)
#Printformattedrequestdataala\'curl-v\'
print(\'\'.join(
\'{line}\\n\'.format(line=line)
forlineinrequest_data.splitlines()
))
self.parse_request(request_data)
#Constructenvironmentdictionaryusingrequestdata
env=self.get_environ()
#It\'stimetocallourapplicationcallableandget
#backaresultthatwillbecomeHTTPresponsebody
result=self.application(env,self.start_response)
#Constructaresponseandsenditbacktotheclient
self.finish_response(result)
defparse_request(self,text):
request_line=text.splitlines()[0]
request_line=request_line.rstrip(\'\\r\\n\')
#Breakdowntherequestlineintocomponents
(self.request_method,#GET
self.path,#/hello
self.request_version#HTTP/1.1
)=request_line.split()
defget_environ(self):
env={}
#ThefollowingcodesnippetdoesnotfollowPEP8conventions
#butit\'sformattedthewayitisfordemonstrationpurposes
#toemphasizetherequiredvariablesandtheirvalues
#
#RequiredWSGIvariables
env[\'wsgi.version\']=(1,0)
env[\'wsgi.url_scheme\']=\'http\'
env[\'wsgi.input\']=StringIO.StringIO(self.request_data)
env[\'wsgi.errors\']=sys.stderr
env[\'wsgi.multithread\']=False
env[\'wsgi.multiprocess\']=False
env[\'wsgi.run_once\']=False
#RequiredCGIvariables
env[\'REQUEST_METHOD\']=self.request_method#GET
env[\'PATH_INFO\']=self.path#/hello
env[\'SERVER_NAME\']=self.server_name#localhost
env[\'SERVER_PORT\']=str(self.server_port)#8888
returnenv
defstart_response(self,status,response_headers,exc_info=None):
#Addnecessaryserverheaders
server_headers=[
(\'Date\',\'Tue,31Mar201512:54:48GMT\'),
(\'Server\',\'WSGIServer0.2\'),
]
self.headers_set=[status,response_headers+server_headers]
#ToadheretoWSGIspecificationthestart_responsemustreturn
#a\'write\'callable.Wesimplicity\'ssakewe\'llignorethatdetail
#fornow.
#returnself.finish_response
deffinish_response(self,result):
try:
status,response_headers=self.headers_set
response=\'HTTP/1.1{status}\\r\\n\'.format(status=status)
forheaderinresponse_headers:
response+=\'{0}:{1}\\r\\n\'.format(*header)
response+=\'\\r\\n\'
fordatainresult:
response+=data
#Printformattedresponsedataala\'curl-v\'
print(\'\'.join(
\'{line}\\n\'.format(line=line)
forlineinresponse.splitlines()
))
self.client_connection.sendall(response)
finally:
self.client_connection.close()
SERVER_ADDRESS=(HOST,PORT)=\'\',8888
defmake_server(server_address,application):
server=WSGIServer(server_address)
server.set_app(application)
returnserver
if__name__==\'__main__\':
iflen(sys.argv)2:
sys.exit(\'ProvideaWSGIapplicationobjectasmodule:callable\')
app_path=sys.argv[1]
module,application=app_path.split(\':\')
module=__import__(module)
application=getattr(module,application)
httpd=make_server(SERVER_ADDRESS,application)
print(\'WSGIServer:ServingHTTPonport{port}...\\n\'.format(port=PORT))
httpd.serve_forever()
这比第一篇的代码长的多,但也足够短(只有150行)来让你理解而避免在细节里越陷越深。上面的服务器可以做更多——可以运行你钟爱web框架所写基本的web应用,Pyramid,Flask,Django,或其他PythonWSGI框架.
不相信我?你自己试试看。保存上面的代码为webserver2.py或者直接在Github下载。如果你不传入任何参数它会提醒然后推出。
$pythonwebserver2.py
ProvideaWSGIapplicationobjectasmodule:callable
前端后端怎么连接起来
前端调用后端接口无外乎六种方法,如下:
1、打开vs,创建空的asp.net mvc演示项目【WebMVC】
(1)依次点击【文件】-【新建】-【项目】;
(2)在【新建项目】界面选择【Web】-【ASP.NET Web 应用程序(.NET Framework)】,输入名称,选择框架至少4.5版本,点击【确定】按钮;
(3)选择【空】-【MVC】-【确定】 ;
(4)创建好了项目。
2、在项目中
(1)在Controllers文件夹上点击鼠标右键,依次选择【添加】-【控制器】,即可完成HomeController的创建;
(2)在Controller的Index方法内,点击鼠标右键,选择【添加视图】;
(3)在项目中添加文件夹【Content】并添加jquery源文件;
(4)在Index页面添加jquery的引用。
3、在Index页面中添加一个输入文本框,一个按钮,以及显示结果的dom。
4、在HomeController中添加新的方法,用于接收前台传入的参数,组装后返回。
5、在Index页面,添加Jquery的ajax方式,调用后台接口,返回结果的处理代码。
6、在vs中,按F5调试运行结果,如下:
(1)在文本框中输入内容;
(2)点击按钮,调用接口,并将返回值显示在界面;
(3)如果要提交大量数据,或者敏感数据,请修改ajax的type方式,这样参数就不会在url地址栏中显示了。
django-restful:与前端vue接口对接
category 与vue 接口对接
首先是需要把所有的category的内容取出来
由于前端vue展示category是分级的
一级 二级 三级 这样展示的
所以我们需要把三个内容都拿出来
但是首先需要取出第一级 然后第一级镶嵌了第二级,然后第二级镶嵌第三季 ,就跟上面goods中显示外键的category的内容一样
我们还是需要写serializer
这样就是一级 镶嵌二级 二级镶嵌三级
但是这里有一个问题不要搞错了 这三个类的位置不能弄错了
因为一级是调用二级 所以二级一定是先写好了的
所以二级一定在一级上面 同理 三级要在二级上面
然后就是view
在过滤中加上category_type = 1 这样就可以直接显示第一大类 然后第一大类中有第二小类 这样更有层次感 如果直接一下子全部取出来 就不好分辨了
同时我们还要处理取出某个单一的信息
所以 我们继承了mixins.RetrieveModelMixin 这个类,这是一个显示详情的类
例如显示某个动物园的某个动物那样
/zoos/id
这样的url
同样这样写了 我们就直接只配置category的url就够了
就不用考虑 后面的id是否还需要配置一个url 这些都不用考虑了,因为我们继承了 viewset这个类
这些问题他都帮我们解决了
这样处理我们后端就能看见了
但是这样处理了 前端对接时 会发现 无法显示
因为有一个跨域问题
这个问题前后端 都可以独自解决 这里学习的是后端,所以讲一下后端的做法
就是修改服务端
在github上搜索django-cors-headers就可以找到这个信息
同样里面介绍如何使用
安装
pip install django-cors-headers
然后settins中INSTALLED_APPS配置和settings中MIDDLEWARE配置
这里要注意 MIDDLEWARE配置中
\'corsheaders.middleware.CorsMiddleware\',
\'django.middleware.common.CommonMiddleware\',
这两个必须放在
\'django.middleware.csrf.CsrfViewMiddleware\',
这个的前面 不然会报错
同时还要配置
CORS_ORIGIN_ALLOW_ALL = True
允许跨域访问 它默认是False
这样前端就可以正常显示了
为什么会产生跨域访问
因为vue中api配置的中 我们调试数据 不可能把所有的host 都修改了 有一些是线上数据 我们调试的是本地的一部分数据 所以要重新定一个localhost
修改部分 host的链接
这样就导致了跨域 本身使用的是一个线上host端口,但是数据中有一部分是请求的是本地host端口 导致了跨域访问
模块化后的前端怎么部署django nginx
以vue框架为例,在nginx.conf中监听80或443端口的server的路由配置设置为:
location ^~ /api { # url如/api/v1.0/user/info等,通过uwsgi转发到django后端项目中处理
include /etc/nginx/uwsgi_params;
uwsgi_pass 127.0.0.1:8077;
include /etc/nginx/mime.types;
}
location ^~ /static { # 后端的资源文件夹为static,前端请求后端项目包内的静态文件
root /root/backend_end_project/static/;
}
location ^~ /admin { # django的后台管理页面通过uwsgi转交给django处理
include /etc/nginx/uwsgi_params;
uwsgi_pass 127.0.0.1:8077;
include /etc/nginx/mime.types;
}
location ^~ /assets { # 前端的资源文件夹为assets,前端请求前端项目包内的静态文件
root /root/front_end_project/dist;
}
location / { # 表示其它路径都交给前端项目根目录下的index.html处理
root /root/front_end_project;
try_files $uri /index.html;
}
结语:以上就是首席CTO笔记为大家整理的关于前端如何调用Django后端的全部内容了,感谢您花时间阅读本站内容,希望对您有所帮助,更多关于前端如何调用Django后端的相关内容别忘了在本站进行查找喔。
以上内容为新媒号(sinv.com.cn)为大家提供!新媒号,坚持更新大家所需的互联网后端知识。希望您喜欢!
版权申明:新媒号所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,不声明或保证其内容的正确性,如发现本站有涉嫌抄袭侵权/违法违规的内容。请发送邮件至 k2#88.com(替换@) 举报,一经查实,本站将立刻删除。