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中字典创建、遍历、添加等实用操作技巧合集
Jun 02 Python
Python二分查找详解
Sep 13 Python
Python 数据结构之旋转链表
Feb 25 Python
Python语言实现将图片转化为html页面
Dec 06 Python
详谈在flask中使用jsonify和json.dumps的区别
Mar 26 Python
python使用PIL实现多张图片垂直合并
Jan 15 Python
python买卖股票的最佳时机(基于贪心/蛮力算法)
Jul 05 Python
django获取from表单multiple-select的value和id的方法
Jul 19 Python
Django之编辑时根据条件跳转回原页面的方法
Aug 21 Python
Pytorch 使用tensor特定条件判断索引
Apr 08 Python
pycharm部署django项目到云服务器的详细流程
Jun 29 Python
关于Python中*args和**kwargs的深入理解
Aug 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
DIY实用性框形天线
2021/03/02 无线电
PHP加速 eAccelerator配置和使用指南
2009/06/05 PHP
PHP中ini_set和ini_get函数的用法小结
2014/02/18 PHP
php语言中使用json的技巧及json的实现代码详解
2015/10/27 PHP
JavaScript设置首页和收藏页面的小例子
2013/11/11 Javascript
js实现checkbox全选、不选与反选的方法
2015/02/09 Javascript
JavaScript中利用Array和Object实现Map的方法
2015/07/27 Javascript
JQUERY实现网页右下角固定位置展开关闭特效的方法
2015/07/27 Javascript
JavaScript中实现Map的示例代码
2015/09/09 Javascript
JS实现的论坛Ajax打分效果完整实例
2015/10/31 Javascript
JavaScript“尽快失败”的原则实例详解
2016/10/08 Javascript
微信小程序开发实战教程之手势解锁
2016/11/18 Javascript
原生js实现无限循环轮播图效果
2017/01/20 Javascript
JS实现JSON.stringify的实例代码讲解
2017/02/07 Javascript
详谈ES6中的迭代器(Iterator)和生成器(Generator)
2017/07/31 Javascript
基于jQuery实现图片推拉门动画效果的两种方法
2017/08/26 jQuery
JS正则表达式完美实现身份证校验功能
2017/10/18 Javascript
vue响应式系统之observe、watcher、dep的源码解析
2019/04/09 Javascript
微信小程序自定义弹窗滚动与页面滚动冲突的解决方法
2019/07/16 Javascript
[05:06]2017亚洲邀请赛DAC回顾片
2017/04/19 DOTA
python登录pop3邮件服务器接收邮件的方法
2015/04/30 Python
Python爬虫获取整个站点中的所有外部链接代码示例
2017/12/26 Python
django如何连接已存在数据的数据库
2018/08/14 Python
Python2和Python3中urllib库中urlencode的使用注意事项
2018/11/26 Python
将Python字符串生成PDF的实例代码详解
2019/05/17 Python
python3图片文件批量重命名处理
2019/10/31 Python
Python爬虫工具requests-html使用解析
2020/04/29 Python
深入浅析css3 中display box使用方法
2015/11/25 HTML / CSS
Canvas在超级玛丽游戏中的应用详解
2021/02/06 HTML / CSS
viagogo英国票务平台:演唱会、体育比赛、戏剧门票
2017/03/24 全球购物
怎样有效的进行自我评价
2013/10/06 职场文书
英文推荐信格式范文
2014/05/09 职场文书
询价采购方案
2014/06/09 职场文书
低碳生活的宣传标语
2014/06/23 职场文书
学术研讨会主持词
2015/07/04 职场文书
2015暑期社会实践调查报告
2015/07/14 职场文书