您的位置:首页 > 编程语言 > Python开发

管理后台-后端-Python篇

2015-12-31 17:10 585 查看
python下的开发框架挺多,Django,Tornado,Flask…,我们选用了Django来做演示是因为Django的restful框架-djangorestframework开发RestfulAPI足够简单成熟。目前Django的最新版本为1.9,而Django从1.7开始已经对Python的最低版本要求到2.7以上了,虽然官方推荐使用Python3,但笔者还是建议使用2.7,因为很多python下的轮子都不是很支持Python3,例如Twisted(Python的网络开发框架)也是最近才开始支持Python3。

我们先搭建基础环境

软件环境:

Python 2.7

Django 1.7以上

djangorestframework

django-cors-headers

我们创建一个Centos6.6的虚拟机,这里做一个小笔记,关于VisualBox如何快速克隆Centos虚拟机:

1.复制虚拟电脑弹出框,勾选重新初始化所有网卡的MAC地址


2.将/etc/udev/rules.d/70-persistent-net.rules中的eth1 MAC地址覆盖到/etc/sysconfig/network-scripts/ifcfg-eth0中的HWADDR,修改DEVICE=eth1

3.重启网络 /etc/init.d/network restart

centos默认的python是2.6的,我们需要下载2.7源码覆盖安装

> yum install -y wget gcc sqlite-devel openssl-devel zlib-devel
> cd /tmp/
> wget https://www.python.org/ftp/python/2.7.10/Python-2.7.10.tgz > tar -xf Python-2.7.10.tgz
> cd Python-2.7.10
> ./configure
> make
> make install
> wget https://bootstrap.pypa.io/ez_setup.py -O - | sudo /usr/local/bin/python
> easy_install django
> easy_install djangorestframework
> easy_install django-cors-headers


创建项目

> django-admin startproject RestfulProject
> cd RestfulProject
> python manage.py startapp database


将database加入到INSTALLED_APPS

# RestfulProject/settings.py
INSTALLED_APPS = (
...
"database",
...
)


数据库建模

# database/models.py
from django.db import models
from django.utils import timezone

class News(models.Model):
title = models.CharField(max_length=100)
content = models.TextField(blank=True)
create_time = models.DateTimeField(default=timezone.now)


将News加入到django的后台自动化管理django-admin中

# database/admin.py
from django.contrib import admin
from .models import *
admin.site.register(News)


数据库初始化

> python manage.py makemigrations database
> python manage.py migrate
> python manage.py createsuperuser


一个Django的基础项目即完成,我们跑起来,看看

> python manage.py runserver 0.0.0.0:8000




我们用djangorestframework来构建最简单的CRUD

# RestfulProject/settings.py
INSTALLED_APPS = (
...
'rest_framework',
)


# RestfulProject/views.py
from rest_framework import serializers,viewsets
from database.models import News

class NewsSerializer(serializers.ModelSerializer):
class Meta:
model = News
class NewsViewSet(viewsets.ModelViewSet):
serializer_class = NewsSerializer
queryset = News.objects.all()


# RestfulProject/urls.py
...
from django.conf.urls import include
from rest_framework import routers
from RestfulProject.views import NewsViewSet

router = routers.DefaultRouter()
router.register(r'news', NewsViewSet,base_name='news')

urlpatterns = [
url(r'^', include(router.urls)),
...
]


我们可以使用postman来测试我们写好的接口,但是djangorestframework本身集成了webapi的在线浏览功能,可以更方便的测试



我们来整合BasicAuth验证功能,djangorestframework的默认验证是使用django自带的session验证,我们首先来看看默认的验证是怎样的

# RestfulProject/views.py
from rest_framework.permissions import IsAuthenticated
class NewsViewSet(viewsets.ModelViewSet):
...
permission_classes = (IsAuthenticated,)


我们再访问这个接口将返回403错误



我们来将默认认证换成BasicAuth

# RestfulProject/settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
],
}


再访问这个接口将返回401错误,浏览器根据该错误将弹出认证界面



按照制定的接口文档,我们再补全一个认证接口给客户端登录使用

# RestfulProject/views.py
from rest_framework.views import APIView
from rest_framework.response import Response

class UserViewSet(APIView):
permission_classes = (IsAuthenticated,)
def get(self, request):
content = {
'userid':request.user.id,
'username':request.user.username,
}
return Response(content)


# RestfulProject/urls.py
from RestfulProject.views import UserViewSet

urlpatterns = [
...
url(r'^auth/info/$', UserViewSet.as_view()),
]


书写扩展的协议-批量删除

编辑RestfulProject/views.py

# RestfulProject/views.py
from rest_framework.decorators import list_route
from rest_framework import status

class NewsViewSet(viewsets.ModelViewSet):
...
@list_route(methods=['delete',])
def deletes(self, request, **kwargs):
ids = request.GET['ids'].split(',')
News.objects.filter(id__in=ids).delete()
return Response(status=status.HTTP_204_NO_CONTENT)


书写扩展协议-搜索

# RestfulProject/views.py
class NewsViewSet(viewsets.ModelViewSet):
serializer_class = NewsSerializer
permission_classes = (IsAuthenticated,)
#queryset = News.objects.all()
def get_queryset(self):
if not 'search' in self.request.GET:
ft = News.objects.all()
else:
ft = News.objects.filter(title__contains=self.request.GET['search'])
return ft.order_by('-create_time')


书写扩展协议-分页

# RestfulProject/pagination.py
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from collections import OrderedDict

class StandardResultsSetPagination(PageNumberPagination):
page_size = 50
page_size_query_param = 'page_size'
max_page_size = 1000
def get_paginated_response(self, data):
return Response(OrderedDict([
('total_count', self.page.paginator.count),
('page_count',self.page.paginator.num_pages),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
]))


# RestfulProject/settings.py
REST_FRAMEWORK = {
...
'DEFAULT_PAGINATION_CLASS': 'RestfulProject.pagination.StandardResultsSetPagination',
}


后端基本完成了,还剩下最后一个问题CORS,我们在本地写一个简单的jquery

<script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
<script>
$.get("http://172.17.9.177:8000/news/");
</script>


在chrome里面调试一下会出现如下错误

XMLHttpRequest cannot load http://172.17.9.177:8000/news/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 401.


我们用django-cors-headers来解决这个问题:

# RestfulProject/settings.py
INSTALLED_APPS = (
...
'corsheaders',
...
)


将cors中间件放置在django.middleware.common.CommonMiddleware之前

# RestfulProject/settings.py
MIDDLEWARE_CLASSES = (
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
)


设置任意网址的跨域请求都被服务器接受

# RestfulProject/settings.py
CORS_ORIGIN_ALLOW_ALL = True


再次用jquery测试,之前那个错误将不再出现。

此文数据库模型、协议的定义参见用Angular搭建管理后台
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: