Python用Django写restful api接口
1.连接数据库
- # 连接数据库,需指定charset否则可能会报错
- db = pymysql.connect(host="localhost", user="root", password="123", db="mysql", charset="utf8mb4")
- cursor = db.cursor() # 创建一个游标对象
2.创建数据库
- cursor.execute("DROP TABLE IF EXISTS meizi_meizis") # 如果表存在则删除
- # 创建表sql语句
- createTab = """create table meizi_meizis(
- id int primary key auto_increment,
- mid varchar(10) not null,
- title varchar(50),
- picname varchar(10),
- page_url varchar(50),
- img_url varchar(50)
- );"""
- cursor.execute(createTab) # 执行创建数据表操作
3.爬取数据
- def html(self, href, title):
- lists = []
- meiziid = href.split('/')[-1]
- html = self.request(href)
- max_span = BeautifulSoup(html.text, 'lxml').find('div', class_='pagenavi').find_all('span')[-2].get_text()
- for page in range(1, int(max_span) + 1):
- meizi = {}
- page_url = href + '/' + str(page)
- img_html = self.request(page_url)
- img_url = BeautifulSoup(img_html.text, 'lxml').find('div', class_='main-image').find('img')['src']
- picname = img_url[-9:-4]
- meizi['meiziid'] = meiziid
- meizi['title'] = title
- meizi['picname'] = picname
- meizi['page_url'] = page_url
- meizi['img_url'] = img_url
- lists.append(meizi) # 保存到返回数组中
- return lists
4.保存到数据库
- def all_url(self, url):
- html = self.request(url)
- all_a = BeautifulSoup(html.text, 'lxml').find('div', class_='all').find_all('a')
- for index, a in enumerate(all_a):
- title = a.get_text()
- href = a['href']
- lists = self.html(href, title)
- for i in lists:
- # print(i['meiziid'], i['title'], i['picname'], i['page_url'], i['img_url'])
- # 插入数据到数据库sql语句,%s用作字符串占位
- sql = "INSERT INTO `meizi_meizis`(`mid`,`title`,`picname`,`page_url`,`img_url`) VALUES(%s,%s,%s,%s,%s)"
- try:
- cursor.execute(sql, (i['meiziid'], i['title'], i['picname'], i['page_url'], i['img_url']))
- db.commit()
- print(i[0] + " is success")
- except:
- db.rollback()
- db.close() # 关闭数据库
5.创建Web工程

然后开始写接口。我是通过Django+rest_framework来写的。
Django 目录结构
Django 常用操作
- INSTALLED_APPS = [
- 'django.contrib.admin',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.messages',
- 'django.contrib.staticfiles',
- 'rest_framework',
- 'meizi',
- ]
- def index(request):
- return HttpResponse(u"你好")
在工程目录urls.py配置
- from learn import views as learn_views
- urlpatterns = [
- url(r'^$', learn_views.index),
- ]
通过python manage.py runserver启动,就会看到我们输出的“你好”了
- class Person(models.Model):
- name = models.CharField(max_length=30)
- age = models.IntegerField()
- def __unicode__(self):
- # 在Python3中使用 def __str__(self):
- return self.name
运行命令,就可以生成对应的表
- Django 1.7.1及以上 用以下命令
- # 1. 创建更改的文件
- python manage.py makemigrations
- # 2. 将生成的py文件应用到数据库
- python manage.py migrate
在views.py文件里就可以获取数据库的数据
- def create(request):
- # 新建一个对象的方法有以下几种:
- Person.objects.create(name='xiaoli', age=18)
- # p = Person(name="WZ", age=23)
- # p = Person(name="TWZ")
- # p.age = 23
- # p.save()
- # 这种方法是防止重复很好的方法,但是速度要相对慢些,返回一个元组,第一个为Person对象,
- # 第二个为True或False, 新建时返回的是True, 已经存在时返回False
- # Person.objects.get_or_create(name="WZT", age=23)
- s = Person.objects.get(name='xiaoli')
- return HttpResponse(str(s))
6.写接口
接口使用rest_framework,rest_framework是一套基于Django 的 REST 框架,是一个强大灵活的构建 Web API 的工具包。
1)连接数据库
- DATABASES = {
- # 'default': {
- # 'ENGINE': 'django.db.backends.sqlite3',
- # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
- # }
- 'default': {
- 'ENGINE': 'django.db.backends.mysql',
- 'NAME': 'mysql',
- 'USER': 'root',
- 'HOST': '127.0.0.1',
- 'PASSWORD': '123',
- 'PORT': 3306,
- # show variables like 'character_set_database';
- # 修改字段字符编码
- # alter table spiders_weibo modify text longtext charset utf8mb4 collate utf8mb4_unicode_ci;
- 'OPTIONS': {'charset': 'utf8mb4'},
- }
- }
2)取数据
- python manage.py inspectdb
可以看到下图

取我们表的model拷贝到app下的models.py里
- class Meizis(models.Model):
- mid = models.CharField(max_length=10)
- title = models.CharField(max_length=50, blank=True, null=True)
- picname = models.CharField(max_length=10, blank=True, null=True)
- page_url = models.CharField(max_length=50, blank=True, null=True)
- img_url = models.CharField(max_length=50, blank=True, null=True)
- class Meta:
- managed = False
- db_table = 'meizi_meizis'
创建一个序列化Serializer类
- class MeiziSerializer(serializers.ModelSerializer):
- # ModelSerializer和Django中ModelForm功能相似
- # Serializer和Django中Form功能相似
- class Meta:
- model = Meizis
- # 和"__all__"等价
- fields = ('mid', 'title', 'picname', 'page_url', 'img_url')
这样在views.py就可以来获取数据库的数据了
- meizis = Meizis.objects.all()
- serializer = MeiziSerializer(meizis, many=True)
- return Response(serializer.data)
3) 数据输出客户端或前端
- @api_view装饰器,基于方法的视图。
- 继承APIView类,基于类的视图。
使用格式后缀明确的指向指定的格式,需要添加一个format关键字参数
http http://127.0.0.1:8000/getlist.json # JSON 后缀
http://127.0.0.1:8000/getlist.api # 可视化 API 后缀
http://127.0.0.1:8000/getlist/ code="print 123"post
- @api_view(['GET', 'POST'])
- def getlist(request, format=None):
- if request.method == 'GET':
- meizis = Meizis.objects.all()
- serializer = MeiziSerializer(meizis, many=True)
- return Response(serializer.data)
- elif request.method == 'POST':
- serializer = MeiziSerializer(data=request.data)
- if serializer.is_valid():
- serializer.save()
- return Response(serializer.data, status=status.HTTP_201_CREATED)
- return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
4)分页




还有个问题
- class StandardResultSetPagination(LimitOffsetPagination):
- # 默认每页显示的条数
- default_limit = 20
- # url 中传入的显示数据条数的参数
- limit_query_param = 'limit'
- # url中传入的数据位置的参数
- offset_query_param = 'offset'
- # 最大每页显示条数
- max_limit = None
在serializers.py创建俩个类,为什么是俩个?因为我们有俩个接口,一个明细,一个列表,而列表是不需要把字段的所有数据都返回的
- class ListSerialize(serializers.ModelSerializer):
- class Meta:
- model = Meizis
- fields = ('mid', 'title')
- class ListPicSerialize(serializers.ModelSerializer):
- class Meta:
- model = Meizis
- fields = "__all__"
- @api_view(['GET'])
- def getlist(request, format=None):
- if request.method == 'GET':
- meizis = Meizis.objects.values('mid','title').distinct()
- # http: // 127.0.0.1:8000 / getlist?limit = 20
- # http: // 127.0.0.1:8000 / getlist?limit = 20 & offset = 20
- # http: // 127.0.0.1:8000 / getlist?limit = 20 & offset = 40
- # 根据url参数 获取分页数据
- obj = StandardResultSetPagination()
- page_list = obj.paginate_queryset(meizis, request)
- # 对数据序列化 普通序列化 显示的只是数据
- ser = ListSerialize(instance=page_list, many=True) # 多个many=True # instance:把对象序列化
- response = obj.get_paginated_response(ser.data)
- return response
- @api_view(['GET', 'POST'])
- def getlispic(request, format=None):
- if request.method == 'GET':
- mid = request.GET['mid']
- if mid is not None:
- # get是用来获取一个对象的,如果需要获取满足条件的一些数据,就要用到filter
- meizis = Meizis.objects.filter(mid=mid)
- obj = StandardResultSetPagination()
- page_list = obj.paginate_queryset(meizis, request)
- ser = ListPicSerialize(instance=page_list, many=True)
- response = obj.get_paginated_response(ser.data)
- return response
- else:
- return Response(str('请传mid'))
Python用Django写restful api接口的更多相关文章
- python 全栈开发,Day95(RESTful API介绍,基于Django实现RESTful API,DRF 序列化)
昨日内容回顾 1. rest framework serializer(序列化)的简单使用 QuerySet([ obj, obj, obj]) --> JSON格式数据 0. 安装和导入: p ...
- Django使用AJAX调用自己写的API接口
Django使用AJAX调用自己写的API接口 *** 具体代码和数据已上传到github https://github.com/PythonerKK/eleme-api-by-django-rest ...
- Django编写RESTful API(一):序列化
欢迎访问我的个人网站:www.comingnext.cn 关于RESTful API 现在,在开发的过程中,我们经常会听到前后端分离这个技术名词,顾名思义,就是前台的开发和后台的开发分离开.这个技术方 ...
- Django编写RESTful API(四):认证和权限
欢迎访问我的个人网站:www.comingnext.cn 前言: 按照前面几篇文章里那样做,使用Django编写RESTful API的基本功能已经像模像样了.我们可以通过不同的URL访问到不同的资源 ...
- SpringMVC Restful api接口实现
[前言] 面向资源的 Restful 风格的 api 接口本着简洁,资源,便于扩展,便于理解等等各项优势,在如今的系统服务中越来越受欢迎. .net平台有WebAPi项目是专门用来实现Restful ...
- 使用Flask设计带认证token的RESTful API接口
大数据时代 Just a record. 使用Flask设计带认证token的RESTful API接口[翻译] 上一篇文章, 使用python的Flask实现一个RESTful API服务器端 简 ...
- Java 调用Restful API接口的几种方式--HTTPS
摘要:最近有一个需求,为客户提供一些Restful API 接口,QA使用postman进行测试,但是postman的测试接口与java调用的相似但并不相同,于是想自己写一个程序去测试Restful ...
- Spring Boot入门系列(二十)快速打造Restful API 接口
spring boot入门系列文章已经写到第二十篇,前面我们讲了spring boot的基础入门的内容,也介绍了spring boot 整合mybatis,整合redis.整合Thymeleaf 模板 ...
- 用 shell 脚本做 restful api 接口监控
问题的提出 基于历史原因,公司有一个"三无"采集服务--无人员.无运维.无监控--有能力做的部门不想接.接了的部门没能力.于是就一直这样裸奔,直到前几天一个依赖于这个采集服务的大数 ...
随机推荐
- 磁盘上没有足够的空间完成此操作的解决办法_Windows小知识
前言: 我们有时候调整系统分区时会遇到"磁盘上没有足够的空间完成此操作"的情况导致我们的分区无法完成,然而我们的磁盘上明明有未分配的空间,为什么不能创建磁盘分区呢?本文将介绍通过把 ...
- 聊聊Spring Cloud版本的那些事儿
说说Spring Cloud版本的那些事儿. 版本命名 之前提到过,Spring Cloud是一个拥有诸多子项目的大型综合项目,原则上其子项目也都维护着自己的发布版本号.那么每一个Spring Clo ...
- linux或Mac中./与/
mac终端命令和linux中命令是一致的,在执行可执行xxx.sh文件时,需要进入xxx.sh文件所在的目录,然后输入./xxx.sh才可以执行成功 1.为什么需要添加./ 因为linux/u ...
- angularJS---自定义过滤器
AngularJS另一个特点就是提供了过滤器,可以通过操作UNIX下管道的方式,操作数据结果. 通过使用管道,可以便于双向的数据绑定中视图的展现. 过滤器在处理过程中,将数据变成新的格式,而且可以使用 ...
- 6.app架构基础
app架构,一个听起来高大尚的名字,很多小伙伴听到这个词语感觉很迷茫,不知道架构具体说的是啥?在q群里,"app后端应该怎么架构"这个问题被问了无数次.通过阅读本文,根据本人提出的 ...
- 跟我学ASP.NET MVC之五:SportsStrore开始
摘要: 这篇文章将介绍一个ASP.NET应用程序SportsStore的开发过程. 开始 创建解决方案 创建工程 在New ASP.NET Project - SportsStore窗口中,选择Emp ...
- 【源码】otter工程结构
最近在搞数据同步相关的内容,需要对otter的代码进行扩展,所以需要先熟悉一下otter的源码.首先我们整体来看下otter的工程结构.otter的工程结构比较复杂,需要花费一定的时间来理解各个部分的 ...
- BZOJ_3687_简单题_bitset
BZOJ_3687_简单题_bitset Description 小呆开始研究集合论了,他提出了关于一个数集四个问题: 1.子集的异或和的算术和. 2.子集的异或和的异或和. 3.子集的算术和的算术和 ...
- [USACO11JAN]大陆议会The Continental Cowngress_2-sat
[USACO11JAN]大陆议会The Continental Cowngress_2-sat 题意: 由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会. 议会以“每头 ...
- BZOJ_3697_采药人的路径_点分治
BZOJ_3697_采药人的路径_点分治 Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材. 采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性 ...