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


具体代码和数据已上传到github

https://github.com/PythonerKK/eleme-api-by-django-restful-framework


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

安装rest framework

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



创建成功会自动安装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编写rest 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'))
]

以下为启动界面



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

如图,测试通过!

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

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

(venv)$ python manage.py startapp front

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

由于篇幅有限,这里贴出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'] +'">' + 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方法是修改局部数据



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

Django使用AJAX调用自己写的API接口的更多相关文章

  1. 如何调用EcStore中的API接口

    EcStore系统已内置了丰富的API接口供外部系统调用(接口列表见文章最下面),外部系统具体如何调用这些API呢? 例如有一个PHP的论坛需要调用ecstore系统内一个商品的详情,则可以使用b2c ...

  2. 第一次写Web API接口

    API是什么?只知道是网络接口,具体怎么写?不会!如何调用?不会!那怎么办? 第一次的经历~~ 需求:为其他项目提供一个接口 功能:为项目提供询盘信息和商家信息,格式为Json字符串 拿过来,就开始做 ...

  3. PC端写的API接口和手机端APP联合调试

    一.遇到问题的情况:项目框架:asp.net MVC5 ,写的给手机端调用的API接口. 二.自己在本地 IIS上部署项目,在手机端的请求服务器上把地址和端口换上本地部署的,如图所示 三.用管理员的身 ...

  4. Python用Django写restful api接口

    用Python如何写一个接口呢,首先得要有数据,可以用我们在网站上爬的数据,在上一篇文章中写了如何用Python爬虫,有兴趣的可以看看: https://www.cnblogs.com/sixrain ...

  5. ajax调用免费的天气API

    最近在做项目中要用到调用天气接口,在网上找了很多资料之后发现https://www.tianqiapi.com/的天气API挺好的,好用而且免费,调用也很简单.在此做个笔记,大家一起学习交流,如有问题 ...

  6. Ajax之调用一言网站API接口

    Ajax的作用,主要是实现局部刷新. 通过老大哥告知,Ajax接口可以使用一言网站的,所以自己就练了一下子. 本文所有用到的接口都来自一言网站:https://hitokoto.cn/api 通过网站 ...

  7. 研发团队如何写好API接口文档

    导读 背景 痛点在哪? 为什么要写接口文档? API规范 接口工具 总结 背景        随着业务的发展,支撑组的项目也是越来越多.同时,从整个支撑组项目架构体系(含运维和运营体系),我们对系统业 ...

  8. 原生Ajax的使用——含开放API接口

    看了两天关于Ajax的使用,总感觉云里雾里的. 故在此总结梳理一下,如果疏漏错误还请纠正支出. Ajax能够在向服务器请求额外的数据时,不必重新加载/卸载整个页面,实现一小块区域性的刷新,也是常说的异 ...

  9. 初识Django —Python API接口编程入门

    初识Django —Python API接口编程入门 一.WEB架构的简单介绍 Django是什么? Django是一个开放源代码的Web应用框架,由Python写成.我们的目标是用Python语言, ...

随机推荐

  1. Java - Iterator源码解析

    java提高篇(三十)-----Iterator 迭代其实我们可以简单地理解为遍历,是一个标准化遍历各类容器里面的所有对象的方法类,它是一个很典型的设计模式.Iterator模式是用于遍历集合类的标准 ...

  2. ScheduledExecutorService的两种方法

    开发中,往往遇到另起线程执行其他代码的情况,用java定时任务接口ScheduledExecutorService来实现. ScheduledExecutorService是基于线程池设计的定时任务类 ...

  3. vue input输入框联想

    以下是示例,样式可以自己修改.最后是效果图,其实也挺简单的,主要是用了watch监控input输入值的变化,如果数据是请后端请求可以,先请求数据. <template> <div c ...

  4. 【读书笔记】iOS-网络-负载

    负载指的是在服务的请求响应事务中交换的数据.常见的负载格式包括XML,JSON与HTML. 进入与发出的负载数据存在很多形式与大小.比如,有些开发者会使用原生的字符串或是以分隔符分开的数据与Web S ...

  5. Mac 上用 Homebrew 安装 .NET Core 1.0 RC4 004771

    年级大了,其实并不是很喜欢升级到最新版,特别是不怎么爱用还没有 Release 的版本了.虽然 .NET Core 已经是 RC4,但毕竟还没有 Release.可过年回来,用 yeoman 创建了一 ...

  6. AngularJS学习之 ui router

    1.安装 bower install --save angular_ui-router 2.在项目主页面 index.html中添加 <div ui-view="">& ...

  7. python学习笔记之——python面向对象

    Python是一门面向对象语言. 1.面向对象技术介绍 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个 ...

  8. openCV 视频分解及合成

    1. 视频分解 import cv2 # ************************** # 分解视频 cap=cv2.VideoCapture('1.mp4')#获取一个视频cap isOpe ...

  9. Python技巧——list与字符串互相转换

    Python技巧——list与字符串互相转换   在Python的编程中,经常会涉及到字符串与list之间的转换问题,下面就将两者之间的转换做一个梳理. 1.字符串转换成list 命令:list() ...

  10. ssh免秘钥配置

    1.要求:两台相同的系统,这里设置server1控制server2的服务器 2.先在两台服务器上都安装好ssh 输入命令下载: yum install -y openssh-clients opens ...