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 接口监控
问题的提出 基于历史原因,公司有一个"三无"采集服务--无人员.无运维.无监控--有能力做的部门不想接.接了的部门没能力.于是就一直这样裸奔,直到前几天一个依赖于这个采集服务的大数 ...
随机推荐
- Masonry中的mas_makeConstraints方法
2018年04月12日 10:10:54 阅读数:138 一.简单介绍 我们一般来说会这样进行使用 [view mas_makeConstraints:^(MASConstraintMaker *ma ...
- 可能是迄今为止最好的GitHub代码浏览插件--赞
https://chrome.google.com/webstore/category/extensions?hl=zh-CN 搜索"insight.io" chrome://ex ...
- Spring Security4.1.3实现拦截登录后向登录页面跳转方式(redirect或forward)返回被拦截界面
一.看下内部原理 简化后的认证过程分为7步: 用户访问网站,打开了一个链接(origin url). 请求发送给服务器,服务器判断用户请求了受保护的资源. 由于用户没有登录,服务器重定向到登录页面 填 ...
- Deep Learning Enables You to Hide Screen when Your Boss is Approaching
https://github.com/Hironsan/BossSensor/ 背景介绍 学生时代,老师站在窗外的阴影挥之不去.大家在玩手机,看漫画,看小说的时候,总是会找同桌帮忙看着班主任有没有来. ...
- c# xml操作(二)
c# xml操作(二) 此博文包含图片 (-- ::)转载▼ 标签: 杂谈 分类: c# 上次,我们介绍了增加和删除xml的一些操作,这次我们将介绍如何更改和读取xml特定节点.我们依然以上次的xml ...
- app后端设计(11)-- 系统架构(2014.12.05更新)
个人认为,在小型的创业团队中,特别是以应用产品为主,在架构后台的时候,需要集中精力解决自身业务上的问题,不是花时间解决第三方已经解决的问题,简单点来说,就是能用第三方服务就使用第三方的服务.基于这个原 ...
- Spring Data Jpa 实现分页(Spring MVC+easyui)
spring data jpa很好的对dao层进行了封装,这篇文章主要来写的是实现easyui datagird数据分页,由于各个UI参数不大一样,所以如果使用的是其他UI,得稍作修改.需要说明的是我 ...
- BDD测试之selenium控制滚动条
一.对于页面存在滚动条,可以通过插入JS控制滚动条(最常用的方法) (1)将滚动条移动到指定坐标位置处 ((JavascriptExecutor) driver).executeScript(&quo ...
- 树莓派.系统.官方下载中NOOBS和Raspbian的区别
树莓派官网(https://www.raspberrypi.org/)官方推荐ROM中主要的有2个: NOOBS---------------------------------- NOOBS 全称 ...
- codeForces 472D 最小生成树
题目大意:给出一个图中点的两两距离,问是否是一棵树,若是,求出平均边权最大的点 prim最小生成树,若原图是树,则最小生成树的距离就是原距离.否则不是. 搞出来树了,第二问随便dfs就好了. #inc ...