经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Django » 查看文章
Django使用AJAX调用自己写的API接口的方法
来源:jb51  时间:2019/3/6 10:34:27  对本文有异议

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

 安装rest framework

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

创建成功会自动安装Django2.1和所需依赖,restframework框架需要自己手动安装

  1. //激活虚拟环境安装以下
  2. (venv)$ pip install djangorestframework
  3. (venv)$ pip install django-filter
  4. (venv)$ pip install pytest
  5. (venv)$ pip install pytest-django
  6. //由于笔者使用Postgresql数据库,所以还需要安装以下
  7. (venv)$ pip install psycopg2
  8. //使用mysql数据库安装如下
  9. (venv)$ pip install pymysql

准备数据来提供服务

数据来源:饿了么爬虫

数据内容:全国所有大学附近的外卖商家Top20

数据需要导入数据库

Django编写rest api接口

项目结构

settings.py.

  1. // 安装的app如下
  2. INSTALLED_APPS = [
  3. #...
  4. 'rest_framework',
  5. 'django_filters',
  6. 'api.apps.ApiConfig',
  7. 'front.apps.FrontConfig',
  8. ]
  9. //restframework 配置如下
  10. REST_FRAMEWORK = {
  11. //这里配置了分页处理,每页最多20个项目
  12. 'DEFAULT_PAGINATION_CLASS':'api.custompagination.LimitOffsetPaginationWithUpperBound',
  13. 'PAGE_SIZE': 20,
  14. 'DEFAULT_FILTER_BACKENDS': (
  15. //这里配置了排序、过滤、搜索器
  16. 'django_filters.rest_framework.DjangoFilterBackend',
  17. 'rest_framework.filters.OrderingFilter',
  18. 'rest_framework.filters.SearchFilter',
  19. ),
  20. //这里配置了用户认证,管理员才可以更改内容,未登录不能更改
  21. 'DEFAULT_AUTHENTICATION_CLASSES':(
  22. 'rest_framework.authentication.BasicAuthentication',
  23. 'rest_framework.authentication.SessionAuthentication',
  24. ),
  25. //这里配置了访问次数限制,过多会返回429错误 too many requests
  26. 'DEFAULT_THROTTLE_CLASSES': (
  27. 'rest_framework.throttling.AnonRateThrottle',
  28. 'rest_framework.throttling.UserRateThrottle',
  29. ),
  30. //这里配置了访问次数,anon代表匿名用户,user代表已登录用户,entries是我自己设置的作用域,300/hour代表最多300次每小时
  31. 'DEFAULT_THROTTLE_RATES': {
  32. 'anon': '300/hour',
  33. 'user': '100/hour',
  34. 'entries': '200/hour',
  35. },
  36. 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.NamespaceVersioning',
  37. }

models.py.

  1. from django.db import models
  2. class Entry(models.Model):
  3. city = models.CharField(max_length=50)
  4. school = models.CharField(max_length=100)
  5. link = models.CharField(max_length=100,null=True,default='null')
  6. name = models.CharField(max_length=200)
  7. lat = models.CharField(max_length=20,null=True,default='0.0')
  8. lng = models.CharField(max_length=20,null=True,default='0.0')
  9. address = models.CharField(max_length=200,null=True,default='null')
  10. distance = models.CharField(max_length=20,null=True,default='0')
  11. time = models.CharField(max_length=20,null=True,default='0:00')
  12. contact = models.CharField(max_length=200,null=True,default='null')
  13. score = models.CharField(max_length=10,null=True,default='0')
  14. comments = models.CharField(max_length=20,null=True,default='0')
  15. sell = models.CharField(max_length=20,null=True,default='0')
  16. image = models.CharField(max_length=200,null=True,default='null')
  17. owner = models.ForeignKey('auth.User',related_name='entries',on_delete=models.CASCADE)
  18. # class Meta:
  19. # ordering = ('name',)
  20. def __str__(self):
  21. return self.name

serializers.py.

  1. from rest_framework import serializers
  2. from api.models import Entry
  3. //这里继承自超链接模型序列器,用于把数据转换为json格式,并且显示链接
  4. class EntrySerializer(serializers.HyperlinkedModelSerializer):
  5. owner = serializers.ReadOnlyField(source='owner.username')
  6. class Meta:
  7. model = Entry
  8. fields = ('url','pk','name','city','school','link','lat','lng','address','distance','time','contact',
  9. 'score','comments','sell','image','owner')

views.py.

  1. from rest_framework import generics
  2. from rest_framework.response import Response
  3. from rest_framework.reverse import reverse
  4. from api.models import Entry
  5. from api.serializers import EntrySerializer
  6. from rest_framework import permissions
  7. from rest_framework.permissions import IsAuthenticated
  8. from rest_framework.throttling import ScopedRateThrottle
  9. from api import custompermission
  10. //这里是获取所有数据,可实现HTTP get、Post、Option操作
  11. class EntryList(generics.ListCreateAPIView):
  12. //限流自定义作用域
  13. throttle_scope = 'entries'
  14. throttle_classes = (ScopedRateThrottle,)
  15. queryset = Entry.objects.all()
  16. serializer_class = EntrySerializer
  17. name = 'entry-list'
  18. filter_fields = ('city','school','name')
  19. search_fields = ('school','city')
  20. ordering_fields = ('city')
  21.  
  22. //管理员才能post操作创建新的数据
  23. permission_classes = (
  24. permissions.IsAuthenticatedOrReadOnly,
  25. custompermission.IsCurrentUserOwnerOrReadOnly,
  26. )
  27. def perform_create(self, serializer):
  28. serializer.save(owner=self.request.user)
  29.  
  30. //这里是获取具体某一项的数据,可实现HTTP GET、PUT、PATCH、Option操作
  31. class EntryDetail(generics.RetrieveUpdateDestroyAPIView):
  32. throttle_scope = 'entries'
  33. throttle_classes = (ScopedRateThrottle,)
  34. queryset = Entry.objects.all()
  35. serializer_class = EntrySerializer
  36. name = 'entry-detail'
  37. permission_classes = (
  38. permissions.IsAuthenticatedOrReadOnly,
  39. custompermission.IsCurrentUserOwnerOrReadOnly,
  40. )
  41. //api根目录
  42. class ApiRoot(generics.GenericAPIView):
  43. name = 'api-root'
  44. def get(self, request, *args, **kwargs):
  45. return Response({
  46. 'entries': reverse(EntryList.name, request=request),
  47. })

urls.py.

  1. from django.urls import path
  2. from api import views
  3. urlpatterns = [
  4. path('entries/', views.EntryList.as_view(), name=views.EntryList.name),
  5. path('entry-detail/<int:pk>', views.EntryDetail.as_view(), name=views.EntryDetail.name),
  6. path('', views.ApiRoot.as_view(), name=views.ApiRoot.name)
  7. ]

ele/urls.py.

  1. from django.urls import path,include
  2. urlpatterns = [
  3. path('v1/',include('api.urls')),
  4. path('v1/api-auth/',include('rest_framework.urls')),
  5. path('',include('front.urls'))
  6. ]

以下为启动界面

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

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

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

  1. (venv)$ python manage.py startapp front

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

由于篇幅有限,这里贴出js代码 使用ajax get请求刚刚写好的api接口并且添加到表格中

myjs.js.

  1. $('#load-more').click(function () {
  2. $.ajax({
  3. method:'GET',
  4. url:api_url,
  5. dataType:'json',
  6. success:function (data) {
  7. api_url = data['next'];
  8. if (api_url == null){
  9. $('#load-more').val('已加载全部');
  10. $('#load-more').attr('disabled',true);
  11. //api_url这里就是刚刚写好的api接口
  12. api_url = 'v1/entries/';
  13. }
  14. var results = data['results'];
  15. for (i=0;i<results.length;i++){
  16. $('#ele-table-body').append(
  17. ' <tr>\n' +
  18. ' <th scope="col">'+results[i]['pk']+'</th>\n' +
  19. ' <th scope="col">'+results[i]['city']+'</th>\n' +
  20. ' <th scope="col"><a href="/detail/' + results[i]['pk'] +'" rel="external nofollow" >' + results[i]['name'] + '</a></th>\n' +
  21. ' <th scope="col">'+results[i]['school']+'</th>\n' +
  22. ' <th scope="col">'+results[i]['score']+'</th>\n' +
  23. ' </tr>'
  24. )
  25. }
  26. }
  27. })
  28. });

可以修改具体的一条数据,使用ajax patch方法提交数据。 注:PUT方法是修改所有数据,而PATCH方法是修改局部数据

myjs.js.

  1. $('#edit-confirm-btn').click(function () {
  2. var name = $('#name').val();
  3. var distance = $('#distance').val();
  4. var adderss = $('#address').val();
  5. var time = $('#time').val();
  6. var score = $('#score').val();
  7. var comments = $('#comments').val();
  8. var sell = $('#sell').val();
  9. var pk = $('#pk').val();
  10. $.ajax({
  11. type:'PATCH',
  12. url:'/detail/' + pk,
  13. data:{
  14. "name": name,
  15. "distance": distance,
  16. "address": adderss,
  17. "time": time,
  18. "score": score,
  19. "comments": comments,
  20. "sell": sell,
  21. },
  22. success:function (data) {
  23. if (data.status == 'ok'){
  24. console.log('success');
  25. location.reload();
  26. }
  27. }
  28. })
  29. })

本文通过一个小例子介绍了如何使用Django调用自己写的api

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号