搭建Python Django-Rest-Framwork详细教程

目前在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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值