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

在这个例子中,我们将使用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'] +'" 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方法是修改局部数据

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接口的方法 的全部内容, 来源链接: utcz.com/z/353873.html

回到顶部