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的ORM框架SQLAlchemy入门教程
Apr 28 Python
Python代码的打包与发布详解
Jul 30 Python
Python for Informatics 第11章之正则表达式(二)
Apr 21 Python
Python调用C++,通过Pybind11制作Python接口
Oct 16 Python
python 获取url中的参数列表实例
Dec 18 Python
解决Django一个表单对应多个按钮的问题
Jul 18 Python
python实现的Iou与Giou代码
Jan 18 Python
pytorch进行上采样的种类实例
Feb 18 Python
python3读取autocad图形文件.py实例
Jun 05 Python
重构Python代码的六个实例
Nov 25 Python
python自动化之如何利用allure生成测试报告
May 02 Python
Django中的JWT身份验证的实现
May 07 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
根德YB400的电路分析
2021/03/02 无线电
在PHP中使用curl_init函数的说明
2010/11/02 PHP
PHP常用的文件操作函数经典收藏
2013/04/02 PHP
PHP实现的XML操作类【XML Library】
2016/12/29 PHP
Laravel框架Eloquent ORM删除数据操作示例
2019/12/03 PHP
用javascript实现的支持lrc歌词的播放器
2007/05/17 Javascript
jQuery 扩展对input的一些操作方法
2009/10/30 Javascript
扩展jQuery 键盘事件的几个基本方法
2009/10/30 Javascript
使图片旋转的3种解决方案
2013/11/21 Javascript
二叉树的非递归后序遍历算法实例详解
2014/02/07 Javascript
Javascript中设置默认参数值示例
2014/09/11 Javascript
jQuery中Ajax的load方法详解
2015/01/14 Javascript
jqueryUI里拖拽排序示例分析
2015/02/26 Javascript
DeviceOne 让你一见钟情的App快速开发平台
2016/02/17 Javascript
如何利用JSHint减少JavaScript的错误
2016/08/23 Javascript
bootstrap模态框消失问题的解决方法
2016/12/02 Javascript
微信小程序 引用其他js文件实现代码
2017/02/22 Javascript
浅谈Vue下使用百度地图的简易方法
2018/03/23 Javascript
Vue+iview+webpack ie浏览器兼容简单处理
2019/09/20 Javascript
微信小程序仿抖音短视频切换效果的实例代码
2020/06/24 Javascript
[01:06]DOTA2小知识课堂 Ep.02 吹风竟可解梦境缠绕
2019/12/05 DOTA
Python使用scrapy采集数据过程中放回下载过大页面的方法
2015/04/08 Python
Python中实现三目运算的方法
2015/06/21 Python
python的多重继承的理解
2017/08/06 Python
Python安装图文教程 Pycharm安装教程
2018/03/27 Python
django如何连接已存在数据的数据库
2018/08/14 Python
python利用7z批量解压rar的实现
2019/08/07 Python
python实现低通滤波器代码
2020/02/26 Python
Python操作PostgreSql数据库的方法(基本的增删改查)
2020/12/29 Python
大学生标准推荐信范文
2013/11/25 职场文书
信息专业个人的自我评价
2013/12/27 职场文书
初中校园广播稿
2014/02/02 职场文书
运动会闭幕词
2015/01/28 职场文书
2015年五一劳动节活动总结
2015/02/09 职场文书
JVM钩子函数的使用场景详解
2021/08/23 Java/Android
Vue实现跑马灯样式文字横向滚动
2021/11/23 Vue.js