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 相关文章推荐
urllib2自定义opener详解
Feb 07 Python
python实现获取客户机上指定文件并传输到服务器的方法
Mar 16 Python
使用Python的Tornado框架实现一个简单的WebQQ机器人
Apr 24 Python
Python抽象类的新写法
Jun 18 Python
node.js获取参数的常用方法(总结)
May 29 Python
使用python的pandas库读取csv文件保存至mysql数据库
Aug 20 Python
Python实现的批量修改文件后缀名操作示例
Dec 07 Python
对matplotlib改变colorbar位置和方向的方法详解
Dec 13 Python
Flask教程之重定向与错误处理实例分析
Aug 01 Python
Python 函数绘图及函数图像微分与积分
Nov 20 Python
python中如何写类
Jun 29 Python
Python实战之OpenCV实现猫脸检测
Jun 26 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+mysql分页代码详解
2008/03/27 PHP
PHP中unset,array_splice删除数组中元素的区别
2014/07/28 PHP
document.createElement()用法及注意事项(ff下不兼容)
2013/03/13 Javascript
jQuery层次选择器选择元素使用介绍
2013/04/18 Javascript
对javascript继承的理解
2016/10/11 Javascript
Bootstrap如何创建表单
2016/10/21 Javascript
jQuery+Ajax实现用户名重名实时检测
2017/06/01 jQuery
vue轮播图插件vue-concise-slider的使用
2018/03/13 Javascript
用vue2.0实现点击选中active其他选项互斥的效果
2018/04/12 Javascript
js jquery 获取某一元素到浏览器顶端的距离实现方法
2018/09/05 jQuery
js中怎么判断两个字符串相等的实例
2019/01/17 Javascript
原生js实现点击轮播切换图片
2020/02/11 Javascript
[46:44]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD BO3 第二场 3月7日
2021/03/11 DOTA
Python中的魔法方法深入理解
2014/07/09 Python
跟老齐学Python之玩转字符串(3)
2014/09/14 Python
Django使用Mysql数据库已经存在的数据表方法
2018/05/27 Python
python梯度下降法的简单示例
2018/08/31 Python
Django跨域请求CSRF的方法示例
2018/11/11 Python
python matplotlib画图库学习绘制常用的图
2019/03/19 Python
Python threading的使用方法解析
2019/08/28 Python
Django数据库操作之save与update的使用
2020/04/01 Python
Python数据库封装实现代码示例解析
2020/09/05 Python
使用phonegap操作数据库的实现方法
2017/03/31 HTML / CSS
Swisse官方海外旗舰店:澳大利亚销量领先,自然健康品牌
2017/12/15 全球购物
英国家庭家具、照明和花园家具购物网站:Furniture123
2018/12/31 全球购物
介绍一下write命令
2014/08/10 面试题
优秀的计算机专业求职信范文
2013/12/27 职场文书
槐乡的孩子教学反思
2014/04/27 职场文书
领导干部学习“三严三实”思想汇报
2014/09/15 职场文书
六年级小学生评语
2014/12/26 职场文书
2015年志愿者服务工作总结
2015/04/20 职场文书
返乡农民工证明
2015/06/24 职场文书
预备党员入党感想
2015/08/10 职场文书
SQL实现LeetCode(178.分数排行)
2021/08/04 MySQL
bat批处理之字符串操作的实现
2022/03/16 Python
Javascript的promise,async和await的区别详解
2022/03/24 Javascript