Python Monitor Water Falls(3)django restful framework

本文详细介绍使用Django REST框架创建RESTful API的过程,包括定义模型、序列化、URL映射及视图实现等关键步骤,并展示了如何部署到生产环境。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python Monitor Water Falls(3)django restful framework

Sqlite browser to see the data
http://sqlitebrowser.org/

Set water record module
>django-admin.py startapp waterrecord

Set up the models.py to define a ORM layer to persist the data in sqlite
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models

class WaterRecord(models.Model):
waterName = models.CharField('water_name', max_length=50)
released = models.BooleanField('released', default = False)
releasedDate = models.CharField('released_date', max_length=20) #2018-01-16
updateTime = models.DateTimeField('update_time', auto_now=True)
createTime = models.DateTimeField('create_time', auto_now_add=True)

def __unicode__(self):
return self.waterName + self.releasedDate

Add this to the settings.py to enable this module
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'restful_api.waterrecord',
]

Models had some changes, so
>./manage.py makemigrations
>./manage.py migrate

Check the Database Information
>python manage.py shell
>>>from restful_api.waterrecord.models import WaterRecord
>>>WaterRecord.objects.all()
<QuerySet [<WaterRecord: MableFalls2018-01-01>, <WaterRecord: MableFalls2018-01-01>, <WaterRecord: MableFalls2018-01-02>]>

Serializer to support the JSON to Python Object and Object to JSON in serializers.py
# -*- coding: utf-8 -*-
from rest_framework import serializers
from .models import WaterRecord

class WaterRecordSerializer(serializers.ModelSerializer):
class Meta:
model = WaterRecord
fields = ('id', 'waterName', 'released', 'releasedDate')

URL Mapping witch is helpful function from the framework in urls.py
# -*- coding: utf-8 -*-
from django.conf.urls import url
from . import views

urlpatterns = [
url(r'^waterrecords/$', views.water_record_list, name='water_record_list'),
# url(r'^waterrecords/$', views.WaterRecordList.as_view(), name='water_record_list'),
# url(r'^waterrecords/$', views.WaterRecordListCreate.as_view(), name='water_record_list'),
url(r'^waterrecords/(?P<pk>[0-9]+)$', views.water_record_detail, name='water_record_detail'),
]

Following the documents, I put a lot of different ways of views.py implementation there, but we only use the last 2 methods
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import generics

from .models import WaterRecord
from .serializers import WaterRecordSerializer

# APIView
class WaterRecordList(APIView):
def get(self, request, format=None):
items = WaterRecord.objects.all()
serializer = WaterRecordSerializer(items, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = WaterRecordSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# ListCreateAPIView
class WaterRecordListCreate(generics.ListCreateAPIView):
queryset = WaterRecord.objects.all()
serializer_class = WaterRecordSerializer

# api_view
@api_view(['GET', 'POST'])
def water_record_list(request):
'''
List all items or create a new item
'''
if request.method == 'GET':
items = WaterRecord.objects.all()
serializer = WaterRecordSerializer(items, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = WaterRecordSerializer(data = request.data)
if serializer.is_valid():
item = serializer.validated_data
result, created = WaterRecord.objects.get_or_create(
waterName=item['waterName'],
releasedDate=item['releasedDate'],
defaults = item)
serializerResult = WaterRecordSerializer(result)
return Response(serializerResult.data, status = status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET', 'PUT', 'DELETE'])
def water_record_detail(request, pk):
try:
item = WaterRecord.objects.get(pk=pk)
except WaterRecord.DoesNotExist:
return Response(status = status.HTTP_404_NOT_FOUND)

if request.method == 'GET':
serializer = WaterRecordSerializer(item)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = WaterRecordSerializer(item, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
item.delete()
return Response(status=status.HTTP_204_NO_CONTENT)

Deployment
Directly run that
>python manage.py runserver

Install the deployment tool
>pip install gunicorn

Libraries, pick up one is fine.
>pip install eventlet
>pip install greenlet
>pip install gevent

It works
>gunicorn restful_api.wsgi

Setting file
>cat gunicorn.py.ini
import multiprocessing

bind = "0.0.0.0:8000"

workers = multiprocessing.cpu_count() * 2 + 1

Run the command
>gunicorn -c gunicorn.py.ini restful_api.wsgi

Command to curl the RESTful API about water record
>curl http://localhost:8000/api/waterrecords/

>curl -X POST http://localhost:8000/api/waterrecords/ -d "waterName=MableFalls&released=true&releasedDate=2018-01-01"

>curl -X DELETE http://localhost:8000/api/waterrecords/1

>curl -X PUT http://localhost:8000/api/waterrecords/2 -d "waterName=MableFalls&released=false&releasedDate=2018-01-01"

I really like to deploy in Docker as follow:
start.sh
#!/bin/sh -ex

#start the service
cd /share/water-monitor/restful_api
gunicorn -c gunicorn.py.ini restful_api.wsgi

Makefile to support the build and run
IMAGE=sillycat/public
TAG=water-monitor-restful-api
NAME=water-monitor-restful-api

docker-context:

build: docker-context
docker build -t $(IMAGE):$(TAG) .

run:
docker run -d -p 8000:8000 -v /opt/water-monitor/restful_api:/share/water-monitor/restful_api --name $(NAME) $(IMAGE):$(TAG)

debug:
docker run -ti -p 8000:8000 -v /opt/water-monitor/restful_api:/share/water-monitor/restful_api --name $(NAME) $(IMAGE):$(TAG) /bin/bash

clean:
docker stop ${NAME}
docker rm ${NAME}

logs:
docker logs ${NAME}

publish:
docker push ${IMAGE}:${TAG}

fetch:
docker pull ${IMAGE}:${TAG}

Dockerfile to adjust all the ENV
#Set up FTP in Docker

#Prepre the OS
FROM resin/raspberrypi3-python
MAINTAINER Carl Luo <luohuazju@gmail.com>

ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -y update
RUN apt-get -y dist-upgrade

#install the software
RUN pip install django
RUN pip install djangorestframework
RUN pip install markdown
RUN pip install django-filter
RUN pip install gunicorn

RUN pip install greenlet
RUN pip install gevent
RUN pip install eventlet

#start the application
EXPOSE 8000
RUN mkdir -p /app/
ADD start.sh /app/
WORKDIR /app/
CMD [ "./start.sh" ]

References:
more example
http://www.cnblogs.com/ccorz/p/djangorestframework-shi-yong-li-zi.html

http://sillycat.iteye.com/blog/2408979

Python Lover
http://sillycat.iteye.com/blog/2116834
http://sillycat.iteye.com/blog/2116836
http://sillycat.iteye.com/blog/2117212
http://sillycat.iteye.com/blog/2117576
http://sillycat.iteye.com/blog/2188140

Python Console
http://sillycat.iteye.com/blog/2372912
http://sillycat.iteye.com/blog/2373528
http://sillycat.iteye.com/blog/2373531
http://sillycat.iteye.com/blog/2373701

http://www.django-rest-framework.org/tutorial/1-serialization/
https://github.com/encode/rest-framework-tutorial
https://github.com/codingforentrepreneurs/Blog-API-with-Django-Rest-Framework
https://github.com/BurkovBA/django-rest-framework-mongoengine-example
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值