`
sillycat
  • 浏览: 2490943 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Python Monitor Water Falls(3)django restful framework

 
阅读更多
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


分享到:
评论

相关推荐

    利用Frank-Wolfe求解UE用户均衡模型,以SiouxFalls网络为例(Python)

    本资源中利用Frank-Wolfe算法求解了SiouxFalls网络的交通分配结果(UE用户均衡结果,即没有用户可以通过单方面改变出行路径从而降低出行费用)。网络基本信息如txt文件所示,路阻函数采用了经典美国联邦公路局BPR...

    Alan Walker All Falls Down.mp3

    Alan Walker All Falls Down.mp3

    [3planesoft屏幕保护程序合集].Premium.3D.Screensavers.iso

    Screen Mountain Waterfall 3D Screensaver will reveal a breathtaking spectacle of the mountain falls away from civilization. Relaxing music and sounds of wild nature will kill you away from the city ...

    PyPI 官网下载 | gravity_falls-0.0.2-py3-none-any.whl

    资源来自pypi官网。 资源全名:gravity_falls-0.0.2-py3-none-any.whl

    Gravitty Falls.exe

    Gravitty Falls.exe

    dijkstra算法代码matlab-GP3:GP3

    Falls路网,如需完整数据和代码请联系。 依赖关系 Python 3.6+ NumPy SciPy 熊猫 网络X CVXOPT MATLAB 2018a 描述 covarianceMatrix.m:生成协方差矩阵的方法 func_GP3.m和func_GP3_accelerate.m:GP3的两种实现方式...

    Get the Day of Week that a Day Falls On

    Get the Day of Week that a Day Falls On

    Gravity Falls Wallpapers New Tab Themes-crx插件

    我们展示了Gravity Falls扩展程序,它将使您的浏览器拥有全新的外观。 通过安装它,您将获得具有完美品质的随机主题,这些主题将在您每次打开新标签页时显示。 这些主题将在您浏览时出现,使您更加享受。 但是,这还...

    Ball_falls.java

    一球从 100 米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在 第 10 次落地时, 共经过多少米?第 10 次反弹多高?

    falls_assignment4

    falls_assignment4

    Gravity Falls wallpaper New Tab-crx插件

    借助Gravity Falls壁纸,您将获得惊人的功能,例如在“新标签”中更改背景 Chrome的Gravity Falls扩展程序会带来什么? 首先,您应该知道,通过引入此Gravity Falls壁纸新标签扩展名,您可以处置掉实际上已经过时的...

    Autumn Falls HD Wallpapers Adult Theme-crx插件

    语言:English (United States) 在每个选项卡背景上均包括视频明星“秋天瀑布”的高清壁纸图像。 安装此扩展程序可在每个新选项卡上获取星空秋天的高清图像!...3:从新标签页中进行简单,直接的搜索

    dijkstra算法代码matlab-GP3:RSP算法

    该文件显示了“高斯过程调节环境中的自适应可靠路径规划”论文中提出的SP、SG、LR和GP3算法的Python和matlab代码。 麦芽实验室文件 maltlab文件夹中包含了四种算法的maltlab代码,由于MATLAB代码太大,无法完整上传...

    NET Reflector 5.0 Release 及19款插件集合

    Assembly Cache: When resolving an assembly reference, Reflector will first search the local path next to the assembly holding the reference and then falls back to the cache directories defined in the ...

    reflector for net C# 反编译利器

    Assembly Cache:When resolving an assembly reference, Reflector will first search the local path next to the assembly holding the reference and then falls back to the cache directories defined in the ...

    反编译软件

    &lt;br&gt;Assembly Cache: When resolving an assembly reference, Reflector will first search the local path next to the assembly holding the reference and then falls back to the cache directories ...

    Peaks-Challenge-Falls-Creek

    Peaks-Challenge-Falls-Creek

    水晶瀑布crystal_falls_VR游戏开发_天空盒子_Skybox_高清_16K_EXR

    可用于UnityVR开发,3D游戏开发,高清天空盒子Skybox素材,游戏环境背景素材,无水印。 让你身临其境的天空盒子,各类... 3-将图片拖入新建的SkyboxMaterial, 4-用刚创建的Material代替项目中原本的系统默认Skybox

    python-lists-lab-data-science-intro-000

    好的,现在我们对如何在Python中读取和更改列表有了一定的了解,让我们来使用这些知识。 目标 练习从列表中读取一个或多个元素 练习更改列表中的数据 练习添加元素和从列表中删除元素 我们的初始数据结构 在上一课中...

Global site tag (gtag.js) - Google Analytics