您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關Python利用Django寫restful api接口的示例的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
前言
用Python如何寫一個接口呢,首先得要有數據,可以用我們在網站上爬的數據。
大量的數據保存到數據庫比較方便。我用的pymsql,pymsql是Python中操作MySQL的模塊,其使用方法和MySQLdb幾乎相同。但目前在python3.x中,PyMySQL取代了MySQLdb。
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 是用Python開發的一個免費開源的Web框架,可以用于快速搭建高性能,優雅的網站。Django 中提供了開發網站經常用到的模塊,常見的代碼都為你寫好了,減少重復的代碼。
Django 目錄結構
urls.py
網址入口,關聯到對應的views.py中的一個函數(或者generic類),訪問網址就對應一個函數。
views.py
處理用戶發出的請求,從urls.py中對應過來, 通過渲染templates中的網頁可以將顯示內容,比如登陸后的用戶名,用戶請求的數據,輸出到網頁。
models.py
與數據庫操作相關,存入或讀取數據時用到這個,當然用不到數據庫的時候 你可以不使用。
forms.py
表單,用戶在瀏覽器上輸入數據提交,對數據的驗證工作以及輸入框的生成等工作,當然你也可以不使用。
templates 文件夾
views.py 中的函數渲染templates中的Html模板,得到動態內容的網頁,當然可以用緩存來提高速度。
admin.py
后臺,可以用很少量的代碼就擁有一個強大的后臺。
settings.py
Django 的設置,配置文件,比如 DEBUG 的開關,靜態文件的位置等。
Django 常用操作
1)新建一個 django project
django-admin.py startproject project_name
2)新建 app
python manage.py startapp app_name
一般一個項目有多個app, 當然通用的app也可以在多個項目中使用。
還得在工程目錄的settings.py文件在配置
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'meizi', ]
在app/views.py下編寫代碼
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啟動,就會看到我們輸出的“你好”了
3)創建數據庫表 或 更改數據庫表或字段
在app下的models.py創建表
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)連接數據庫
在工程目錄下的settings.py文件下配置
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)取數據
既然要取數據,那model肯定得和數據庫的一致,我發現一個快捷的方式可以把數據庫中的表生成對應的model,在項目目錄下執行命令
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類
提供序列化和反序列化的途徑,使之可以轉化為,某種表現形式如json。我們可以借助serializer來實現,類似于Django表單(form)的運作方式。在app目錄下,創建文件serializers.py。
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) 數據輸出客戶端或前端
REST框架提供了兩種編寫API視圖的封裝。
@api_view裝飾器,基于方法的視圖。
繼承APIView類,基于類的視圖。
request.data會自行處理輸入的json請求
使用格式后綴明確的指向指定的格式,需要添加一個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)分頁
最后別忘了在urls.py配置URL,通過瀏覽器就可以看到json數據了。
當然app也是可以調用我們的接口的
還有個問題
我們的數據有好幾千條,一塊返回來很不合理,所以需要分頁,當然rest_framework框架提供了這個功能,post請求不支持,需要自己查數據庫或者切片來進行返回。來看看rest_framework是如何來分頁的。在models.py里創建一個類
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__"
在views.py里編寫
@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接口的示例”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。