目前在web app后台有各种技术和框架 经过多年的发展 动态语言逐渐成为主流。动态语言中以nodejs得到最广泛的应用。但python也有自己的优势 其数据处理能力特别强 所以就对python中比较热门的框架Django-Rest-Framwork做一个入门教程。
网上有关Django-Rest-Framwork的技术文章大多没头没脑的 让人看了云里雾里。更要命的是Django-Rest-Framwork的官方文章也写得不好 让人看了不知所以然。本文以一个开发案例细述每一个步骤。本案例参考了 django rest framework实战 (django rest framework实战 - 简书)。注 这个连接里的案例代码有很多错误 是跑不起来的。也许以前能跑 但没有交代清楚版本。
1. 安装Phthon-v3.7.9。
2. 运行下面命令安装python库。
pip install Django djangorestframework requests pip install markdown # Markdown support for the browsable API. pip install django-filter # Filtering support
装好python库后运行命令 pip list 看一下python库的版本
Django 3.2.7 django-filter 2.4.0 djangorestframework 3.12.4
3. 先选择好一个开发目录 然后运行下面命令生成一个工程Project
django-admin startproject DjangoRestProj1 cd DjangoRestProj1
4. 运行下面命令 在这个工程下新建一个名为blog的App。
django-admin startapp blog
5. 修改DjangoRestProj1/settings.py 增加INSTALLED_APPS REST_frameWORK和静态文件服务器的路径设置。
INSTALLED_APPS [
django.contrib.admin ,
django.contrib.auth ,
django.contrib.contenttypes ,
django.contrib.sessions ,
django.contrib.messages ,
django.contrib.staticfiles ,
rest_framework ,
blog ,
#add to your settings.py
REST_frameWORK {
DEFAULT_PERMISSION_CLASSES : [
rest_framework.permissions.AllowAny ,
DEFAULT_PAGINATION_CLASS : rest_framework.pagination.PageNumberPagination ,
PAGE_SIZE : 10
#define folder for static file server
STATIC_URL /static/
#STATIC_ROOT os.path.join(base_DIR, static )
STATICFILES_DIRS [
os.path.join(base_DIR, static ),
6. 修改blog/models.py实现数据模型。
from django.db import models # Create your models here. class User(models.Model): username models.CharField(max_length 20,null False) password models.CharField(max_length 20,null False) name models.CharField(max_length 10,null False) #name class meta: ordering [ username ] class Blog(models.Model): title models.CharField(max_length 50,null False) body models.TextField() owner models.ForeignKey(User, on_delete models.CASCADE) #creator of blog create_date models.DateTimeField(auto_now_add True) def __str__(self): return self.title class meta: ordering [ -create_date ]
7. 新建blog/serializers.py实现对模型的序列化处理。
from rest_framework import serializers from blog.models import * class BlogSerializer(serializers.ModelSerializer): owner serializers.ReadonlyField(source owner.name ) #只读 class meta: exclude [] model Blog fields ( id , title , body , owner ) #user register, return json of user class UserRegisterSerializer(serializers.ModelSerializer): class meta: exclude [] model User field ( id , username , name ) class UserSerializer(serializers.ModelSerializer): blog_set serializers.PrimaryKeyRelatedField(many True, queryset Blog.objects.all()) class meta: exclude [] model User field ( id , username , blog_set )
8. 新建blog/permissions.py实现权限管理。
#coding utf-8 from rest_framework import permissions class IsOwnerOrReadonly(permissions.basePermission): def has_permission(self, request, view): if request.method in permissions.SAFE_METHODS: return True #session_userid request.session.get( user_id ) return request.session.get( user_id ) is not None def has_object_permission(self, request, view, blog): # Read permissions are allowed to any request, # so we ll always allow GET, HEAD or OPTIONS requests. if request.method in permissions.SAFE_METHODS: return True return blog.owner.id request.session.get( user_id )
9. 修改blog/views.py实现restful API.
# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.shortcuts import render # Create your views here. from rest_framework import viewsets from rest_framework.permissions import AllowAny from rest_framework.response import Response from rest_framework.status import HTTP_200_OK, HTTP_400_BAD_REQUEST from rest_framework.views import APIView from blog.permissions import IsOwnerOrReadonly from blog.serializers import * #login class UserLoginAPIView(APIView): queryset User.objects.all() serializer_class UserSerializer permission_classes (AllowAny,) def post(self, request, format None): data request.data username data.get( username ) password data.get( password ) user User.objects.get(username__exact username) if user.password password: serializer UserSerializer(user) new_data serializer.data # save user to session self.request.session[ user_id ] user.id seesionUserid request.session.get( user_id ) return Response(new_data, status HTTP_200_OK) return Response( password error , HTTP_400_BAD_REQUEST) #register class UserRegisterAPIView(APIView): queryset User.objects.all() serializer_class UserRegisterSerializer permission_classes (AllowAny,) def post(self, request, format None): data request.data username data.get( username ) if User.objects.filter(username__exact username): return Response( Username already existed ,HTTP_400_BAD_REQUEST) serializer UserRegisterSerializer(data data) if serializer.is_valid(raise_exception True): serializer.save() return Response(serializer.data,status HTTP_200_OK) return Response(serializer.errors, status HTTP_400_BAD_REQUEST) #add, delete, modify, query function for blog. All function need permission except query class BlogViewSet(viewsets.ModelViewSet): queryset Blog.objects.all() serializer_class BlogSerializer permission_classes (IsOwnerOrReadOnly,) def perform_create(self, serializer): #print(self.request.user) serializer.save(owner User.objects.get(id self.request.session.get( user_id ))) class UserViewSet(viewsets.ModelViewSet): queryset User.objects.all() serializer_class UserSerializer
10 修改DjangoRestProj1/urls.py配置路由。
restProj URL Configuration The urlpatterns list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/3.2/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path( , views.home, name home ) Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path( , Home.as_view(), name home ) Including another URLconf 1. import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path( blog/ , include( blog.urls )) from django.conf.urls import url,include from django.contrib import admin from django.urls import path from rest_framework import routers from django.conf.urls.static import static from django.conf import settings from blog.views import * router routers.DefaultRouter() router.register(r users ,UserViewSet) router.register(r blogs ,BlogViewSet) urlpatterns [ url(r ^api/ ,include(router.urls)), path( admin/ , admin.site.urls), url(r ^api/register ,UserRegisterAPIView.as_view()), url(r ^api/login ,UserLoginAPIView.as_view()), ] static(settings.STATIC_URL, document_root settings.STATIC_ROOT)
11. 运行下面命令初始化数据库:
python manage.py makemigrations python manage.py migrate
12. 运行下面命令启动restful API服务:
python manage.py runserver
13. 使用工具测试, 使用chrome插件测试restful API, 安装和使用Chrome Extension:PostWoman Http Test。下面是用PostWoman测试的图片。
测试用例1: 用户注册:
URL: http://localhost:8000/api/register
Method:Post
Fotmat:Custom--application/json
JSon: { username : ICELEE , password : mypass , name : icelee }
测试用例2 增加一个blog, 你将会得到报错信息 因为你还没登录。
URL: http://localhost:8000/api/blogs/
Method:Post
Fotmat:Custom--application/json
JSon: { title : My first blog , body : Oh Ya, Nice }
测试用例3 用户登录。
URL: http://localhost:8000/api/login/
Method:Post
Fotmat:Custom--application/json
JSon: { username : ICELEE , password : mypass }
测试用例4 增加一个blog, 你将会得到操作成功信息。
URL: http://localhost:8000/api/blogs/
Method:Post
Fotmat:Custom--application/json
JSon: { title : My second blog , body : Oh Ye, Nice }
最后 本案例的全部代码在GitHub - gordon518/DjangoRestProj1



