Django使用AJAX调用自己写的API接口的方法


Posted in Python onMarch 06, 2019

在这个例子中,我们将使用Django编写饿了么高校外卖商家查询API接口,并且使用AJAX技术来实现API接口的使用,包括使用ajax get方法加载更多数据,使用ajax方法来更新、修改、新增、删除数据。利用API可以做到前后端分离,为开发web应用提供了便利。

 安装rest framework

首先使用Pycharm新建一个Django项目,并且使用virtualenv或者pipenv虚拟环境

Django使用AJAX调用自己写的API接口的方法

创建成功会自动安装Django2.1和所需依赖,restframework框架需要自己手动安装

//激活虚拟环境安装以下
(venv)$ pip install djangorestframework
(venv)$ pip install django-filter 
(venv)$ pip install pytest
(venv)$ pip install pytest-django 
//由于笔者使用Postgresql数据库,所以还需要安装以下
(venv)$ pip install psycopg2
//使用mysql数据库安装如下
(venv)$ pip install pymysql

准备数据来提供服务

数据来源:饿了么爬虫

数据内容:全国所有大学附近的外卖商家Top20

数据需要导入数据库

Django使用AJAX调用自己写的API接口的方法

Django编写rest api接口

项目结构

Django使用AJAX调用自己写的API接口的方法

settings.py.

// 安装的app如下
INSTALLED_APPS = [
 #...
 'rest_framework',
 'django_filters',
 'api.apps.ApiConfig',
 'front.apps.FrontConfig',
]
//restframework 配置如下
REST_FRAMEWORK = {
//这里配置了分页处理,每页最多20个项目
'DEFAULT_PAGINATION_CLASS':'api.custompagination.LimitOffsetPaginationWithUpperBound',
 'PAGE_SIZE': 20,
 'DEFAULT_FILTER_BACKENDS': (
 //这里配置了排序、过滤、搜索器
 'django_filters.rest_framework.DjangoFilterBackend',
 'rest_framework.filters.OrderingFilter',
 'rest_framework.filters.SearchFilter',
 ),
 //这里配置了用户认证,管理员才可以更改内容,未登录不能更改
 'DEFAULT_AUTHENTICATION_CLASSES':(
 'rest_framework.authentication.BasicAuthentication',
 'rest_framework.authentication.SessionAuthentication',
 ),
 //这里配置了访问次数限制,过多会返回429错误 too many requests
 'DEFAULT_THROTTLE_CLASSES': (
 'rest_framework.throttling.AnonRateThrottle',
 'rest_framework.throttling.UserRateThrottle',
 ),
 //这里配置了访问次数,anon代表匿名用户,user代表已登录用户,entries是我自己设置的作用域,300/hour代表最多300次每小时
 'DEFAULT_THROTTLE_RATES': {
 'anon': '300/hour',
 'user': '100/hour',
 'entries': '200/hour',
 },
 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.NamespaceVersioning',
}

models.py.

from django.db import models
class Entry(models.Model):
 city = models.CharField(max_length=50)
 school = models.CharField(max_length=100)
 link = models.CharField(max_length=100,null=True,default='null')
 name = models.CharField(max_length=200)
 lat = models.CharField(max_length=20,null=True,default='0.0')
 lng = models.CharField(max_length=20,null=True,default='0.0')
 address = models.CharField(max_length=200,null=True,default='null')
 distance = models.CharField(max_length=20,null=True,default='0')
 time = models.CharField(max_length=20,null=True,default='0:00')
 contact = models.CharField(max_length=200,null=True,default='null')
 score = models.CharField(max_length=10,null=True,default='0')
 comments = models.CharField(max_length=20,null=True,default='0')
 sell = models.CharField(max_length=20,null=True,default='0')
 image = models.CharField(max_length=200,null=True,default='null')
 owner = models.ForeignKey('auth.User',related_name='entries',on_delete=models.CASCADE)
 # class Meta:
 # ordering = ('name',)
 def __str__(self):
 return self.name

serializers.py.

from rest_framework import serializers
from api.models import Entry
//这里继承自超链接模型序列器,用于把数据转换为json格式,并且显示链接
class EntrySerializer(serializers.HyperlinkedModelSerializer):
 owner = serializers.ReadOnlyField(source='owner.username')
 class Meta:
 model = Entry
 fields = ('url','pk','name','city','school','link','lat','lng','address','distance','time','contact',
 'score','comments','sell','image','owner')

views.py.

from rest_framework import generics
from rest_framework.response import Response
from rest_framework.reverse import reverse
from api.models import Entry
from api.serializers import EntrySerializer
from rest_framework import permissions
from rest_framework.permissions import IsAuthenticated
from rest_framework.throttling import ScopedRateThrottle
from api import custompermission
//这里是获取所有数据,可实现HTTP get、Post、Option操作
class EntryList(generics.ListCreateAPIView):
 //限流自定义作用域
 throttle_scope = 'entries'
 throttle_classes = (ScopedRateThrottle,)
 queryset = Entry.objects.all()
 serializer_class = EntrySerializer
 name = 'entry-list'
 filter_fields = ('city','school','name')
 search_fields = ('school','city')
 ordering_fields = ('city')

 //管理员才能post操作创建新的数据
 permission_classes = (
 permissions.IsAuthenticatedOrReadOnly,
 custompermission.IsCurrentUserOwnerOrReadOnly,
 )
 def perform_create(self, serializer):
 serializer.save(owner=self.request.user)

//这里是获取具体某一项的数据,可实现HTTP GET、PUT、PATCH、Option操作
class EntryDetail(generics.RetrieveUpdateDestroyAPIView):
 throttle_scope = 'entries'
 throttle_classes = (ScopedRateThrottle,)
 queryset = Entry.objects.all()
 serializer_class = EntrySerializer
 name = 'entry-detail'
 permission_classes = (
 permissions.IsAuthenticatedOrReadOnly,
 custompermission.IsCurrentUserOwnerOrReadOnly,
 )
//api根目录
class ApiRoot(generics.GenericAPIView):
 name = 'api-root'
 def get(self, request, *args, **kwargs):
 return Response({
 'entries': reverse(EntryList.name, request=request),
 })

urls.py.

from django.urls import path
from api import views
urlpatterns = [
 path('entries/', views.EntryList.as_view(), name=views.EntryList.name),
 path('entry-detail/<int:pk>', views.EntryDetail.as_view(), name=views.EntryDetail.name),
 path('', views.ApiRoot.as_view(), name=views.ApiRoot.name)
]

ele/urls.py.

from django.urls import path,include
urlpatterns = [
 path('v1/',include('api.urls')),
 path('v1/api-auth/',include('rest_framework.urls')),
 path('',include('front.urls'))
]

以下为启动界面

Django使用AJAX调用自己写的API接口的方法

Django使用AJAX调用自己写的API接口的方法

到此为止非常简单的api就写完了,接下来就是自动化测试是否达到预期效果。 如图,测试通过!

Django使用AJAX调用自己写的API接口的方法

在程序中调用刚刚写好的api

创建一个新的app并且添加到settings.py里面

(venv)$ python manage.py startapp front

做好的效果如下:点击加载更多会触发ajax

Django使用AJAX调用自己写的API接口的方法

Django使用AJAX调用自己写的API接口的方法

由于篇幅有限,这里贴出js代码 使用ajax get请求刚刚写好的api接口并且添加到表格中

myjs.js.

$('#load-more').click(function () {
 $.ajax({
 method:'GET',
 url:api_url,
 dataType:'json',
 success:function (data) {
 api_url = data['next'];
 if (api_url == null){
 $('#load-more').val('已加载全部');
 $('#load-more').attr('disabled',true);
 //api_url这里就是刚刚写好的api接口
 api_url = 'v1/entries/';
 }
 var results = data['results'];
 for (i=0;i<results.length;i++){
 $('#ele-table-body').append(
 ' <tr>\n' +
 ' <th scope="col">'+results[i]['pk']+'</th>\n' +
 ' <th scope="col">'+results[i]['city']+'</th>\n' +
 ' <th scope="col"><a href="/detail/' + results[i]['pk'] +'" rel="external nofollow" >' + results[i]['name'] + '</a></th>\n' +
 ' <th scope="col">'+results[i]['school']+'</th>\n' +
 ' <th scope="col">'+results[i]['score']+'</th>\n' +
 ' </tr>'
 )
 }
 }
 })
 });

可以修改具体的一条数据,使用ajax patch方法提交数据。 注:PUT方法是修改所有数据,而PATCH方法是修改局部数据

Django使用AJAX调用自己写的API接口的方法

myjs.js.

$('#edit-confirm-btn').click(function () {
 var name = $('#name').val();
 var distance = $('#distance').val();
 var adderss = $('#address').val();
 var time = $('#time').val();
 var score = $('#score').val();
 var comments = $('#comments').val();
 var sell = $('#sell').val();
 var pk = $('#pk').val();
 $.ajax({
 type:'PATCH',
 url:'/detail/' + pk,
 data:{
 "name": name,
 "distance": distance,
 "address": adderss,
 "time": time,
 "score": score,
 "comments": comments,
 "sell": sell,
 },
 success:function (data) {
 if (data.status == 'ok'){
 console.log('success');
 location.reload();
 }
 }
 })
 })

本文通过一个小例子介绍了如何使用Django调用自己写的api

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之不要红头文件(1)
Sep 28 Python
python字符串替换的2种方法
Nov 30 Python
在Python程序中实现分布式进程的教程
Apr 28 Python
Python+matplotlib实现华丽的文本框演示代码
Jan 22 Python
详解python的ORM中Pony用法
Feb 09 Python
纯用NumPy实现神经网络的示例代码
Oct 24 Python
python pexpect ssh 远程登录服务器的方法
Feb 14 Python
详解python中init方法和随机数方法
Mar 13 Python
python面试题Python2.x和Python3.x的区别
May 28 Python
Python流行ORM框架sqlalchemy安装与使用教程
Jun 04 Python
Python 简单计算要求形状面积的实例
Jan 18 Python
Python 程序员必须掌握的日志记录
Aug 17 Python
Django+Xadmin构建项目的方法步骤
Mar 06 #Python
Python中最大递归深度值的探讨
Mar 05 #Python
Python小进度条显示代码
Mar 05 #Python
Python嵌套式数据结构实例浅析
Mar 05 #Python
Python字典遍历操作实例小结
Mar 05 #Python
Python字典的基本用法实例分析【创建、增加、获取、修改、删除】
Mar 05 #Python
Python之lambda匿名函数及map和filter的用法
Mar 05 #Python
You might like
php从右向左/从左向右截取字符串的实现方法
2011/11/28 PHP
php连接mssql的一些相关经验及注意事项
2013/02/05 PHP
php获取文件名后缀常用方法小结
2015/02/24 PHP
PHP解密Unicode及Escape加密字符串
2015/05/17 PHP
PHP实现的简单网络硬盘
2015/07/29 PHP
PHP的Json中文处理解决方案
2016/09/29 PHP
基于jquery的高性能td和input切换并可修改内容实现代码
2011/01/09 Javascript
javascript不同类型数据之间的运算的转换方法
2014/02/13 Javascript
js获得当前时区夏令时发生和终止的时间代码
2014/02/23 Javascript
基于javascript实现文字无缝滚动效果
2016/03/22 Javascript
移动端横屏的JS代码(beta)
2016/05/16 Javascript
webpack构建vue项目的详细教程(配置篇)
2017/07/17 Javascript
layui结合form,table的全选、反选v1.0示例讲解
2018/08/15 Javascript
使vue实现jQuery调用的两种方法
2019/05/12 jQuery
解决包含在label标签下的checkbox在ie8及以下版本点击事件无效果兼容的问题
2019/10/27 Javascript
详解React 元素渲染
2020/07/07 Javascript
[36:09]Secret vs VG 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.24
2019/09/10 DOTA
Python3基础之条件与循环控制实例解析
2014/08/13 Python
Python判断字符串与大小写转换
2015/06/08 Python
python利用拉链法实现字典方法示例
2017/03/25 Python
Python 40行代码实现人脸识别功能
2017/04/02 Python
pygame游戏之旅 添加游戏介绍
2018/11/20 Python
Python实现图片转字符画的代码实例
2019/02/22 Python
使用python的pandas为你的股票绘制趋势图
2019/06/26 Python
Python将文字转成语音并读出来的实例详解
2019/07/15 Python
python3 使用Opencv打开USB摄像头,配置1080P分辨率的操作
2019/12/11 Python
python图形开发GUI库wxpython使用方法详解
2020/02/14 Python
详解torch.Tensor的4种乘法
2020/09/03 Python
python如何写个俄罗斯方块
2020/11/06 Python
如何基于Python和Flask编写Prometheus监控
2020/11/25 Python
strstr()的简单实现
2013/09/26 面试题
毕业生文员求职信
2013/11/03 职场文书
党员组织关系介绍信
2014/02/13 职场文书
技校学生个人职业生涯规划范文
2014/03/03 职场文书
医院保洁员岗位职责
2015/02/13 职场文书
2016年中学端午节主题活动总结
2016/04/01 职场文书