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网站验证码识别
Jan 25 Python
Python批量合并有合并单元格的Excel文件详解
Apr 05 Python
Python实现的连接mssql数据库操作示例
Aug 17 Python
python采集微信公众号文章
Dec 20 Python
Python变量访问权限控制详解
Jun 29 Python
OpenCV+face++实现实时人脸识别解锁功能
Aug 28 Python
简单了解python调用其他脚本方法实例
Mar 26 Python
Keras搭建自编码器操作
Jul 03 Python
在django中实现choices字段获取对应字段值
Jul 12 Python
Python 忽略文件名编码的方法
Aug 01 Python
PyQt5多线程防卡死和多窗口用法的实现
Sep 15 Python
jupyter notebook远程访问不了的问题解决方法
Jan 11 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处理CSV表格文件的常用操作方法总结
2016/07/01 PHP
tp5框架使用composer实现日志记录功能示例
2019/01/10 PHP
jquery animate 动画效果使用说明
2009/11/04 Javascript
js实现飞入星星特效代码
2014/10/17 Javascript
Bootstrap学习笔记之css样式设计(2)
2016/06/07 Javascript
Bootstrap 轮播(Carousel)插件
2016/12/26 Javascript
微信小程序 限制1M的瘦身技巧与方法详解
2017/01/06 Javascript
AngularJS使用ng-inlude指令加载页面失败的原因与解决方法
2017/01/19 Javascript
利用js定义一个导航条菜单
2017/03/14 Javascript
jquery实现全选、全不选以及单选功能
2017/03/23 jQuery
Angular获取手机验证码实现移动端登录注册功能
2017/05/17 Javascript
深入理解Angular4订阅(Subscribe)与取消
2017/11/22 Javascript
JS实现图片转换成base64的各种应用场景实例分析
2018/06/22 Javascript
微信小程序解除10个请求并发限制
2018/12/18 Javascript
nodeJS进程管理器pm2的使用
2019/01/09 NodeJs
解决ie11 SCRIPT5011:不能执行已释放Script的代码问题
2019/05/05 Javascript
JS代码屏蔽F12,右键,粘贴,复制,剪切,选中,操作实例
2019/09/17 Javascript
解决vuex数据页面刷新后初始化操作
2020/07/26 Javascript
Python牛刀小试密码爆破
2011/02/03 Python
pygame学习笔记(5):游戏精灵
2015/04/15 Python
关于Django显示时间你应该知道的一些问题
2017/12/25 Python
python使用folium库绘制地图点击框
2018/09/21 Python
用Python实现数据的透视表的方法
2018/11/16 Python
关于python之字典的嵌套,递归调用方法
2019/01/21 Python
Python开发之pip安装及使用方法详解
2020/02/21 Python
python多线程semaphore实现线程数控制的示例
2020/08/10 Python
写一个方法1000的阶乘
2012/11/21 面试题
如果NULL和0作为空指针常数是等价的,那我到底该用哪一个
2014/09/16 面试题
什么是网络协议
2016/04/07 面试题
个人求职简历的自我评价范文
2013/10/09 职场文书
如何写一份好的自荐信
2014/01/02 职场文书
教师演讲稿大全
2014/05/16 职场文书
2014年十一国庆节活动方案
2014/09/16 职场文书
开展批评与自我批评发言材料
2014/10/17 职场文书
工作经验交流材料
2014/12/30 职场文书
vue项目支付功能代码详解
2022/02/18 Vue.js