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/', 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

  $('#ele-table-body').append(

  '

  ' +

  ' '+results[i]['pk']+'

  ' +

  ' '+results[i]['city']+'

  ' +

  ' ' + results[i]['name'] + '

  ' +

  ' '+results[i]['school']+'

  ' +

  ' '+results[i]['score']+'

  ' +

  ' '

  )

  }

  }

  })

  });

  可以修改具体的一条数据,使用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

  以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  您可能感兴趣的文章: