使用django开发restful接口


前言

django学了也挺久的了,但对于django开发自己总是感觉不如人意,可能是基础的架构没有建设好,作为半路转行的人员来说,夯实基础尤为重要。趁着这个周末,利用django进行了一波开发学习。初衷是为了让自己更好的入门理解django开发。

本文是一个简单的用户管理系统。

开发环境配置

  • python版本——3.7.7
  • IDE——pycharm2019.3.3
  • django——2.2.17
  • postman

django中的开发接口有两种模式FBV和CBV,分别是基于函数视图基于类视图,详细的可以看看菜鸟教程的Django 视图 - FBV 与 CBV,由于本文的用户管理是一个restful风格的api,所以我选择的是类视图的开发风格。

进入开发

首先我们使用django-admin命令创建一个新项目:

django-admin startproject userapi

然后进入项目

cd userapi

然后创建项目虚拟环境并在虚拟环境中安装django

image-20201108181926082

接着我们创建一个用户管理系统app

python manage.py startapp usermanage

然后我们就使用pycharm打开我们在命令行创建的这个项目吧。

目前pycharm创建的django项目使用的django版本是3.X版本,但是我们还是先使用2.2LTS版本吧

image-20201108182338971

可以看到项目的结构和目录如pycharm的截图所示。

django设置

首先我们需要在django设置中改动几处位置。

  • 首先我们创建的app需要在django设置文件中进行注册

    image-20201108182635425

  • 然后在更改语言和地区

    image-20201108182819406

然后我们启动一下,看一下我们的django是否正常。

在命令行输入

python manage.py runserver 8000

image-20201108183007076

可以看到我们已经启动成功了,不过提示我们需要运行什么命令,下面在解决,我们先打开网页看看有没有问题。

image-20201108183121512

数据库配置

接下来我们要做的第一件事情就是我们要打开usermanageapp的models文件,创建数据库模型。数据库配置就是用django默认的。

usermanage/models.py

from django.db import models


# Create your models here.
class Users(models.Model):
    SEX_ITEMS = (
        (2, '未知'),
        (1, '男'),
        (0, '女'),
    )
    name = models.CharField(max_length=128, verbose_name='姓名')
    sex = models.IntegerField(choices=SEX_ITEMS, default=2, verbose_name='性别')
    idcard = models.CharField(max_length=18, verbose_name='身份证号码', unique=True)
    email = models.EmailField(verbose_name='邮箱地址')
    address = models.CharField(max_length=256, verbose_name='家庭住址')
    company = models.CharField(max_length=256, verbose_name='所属公司')
    created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = verbose_name_plural = '用户管理'

数据库创建好了,现在我们就要解决刚才的启动django时的提示了。

我们在命令行输入两条命令:

image-20201108183725782

image-20201108183805242

可以看到命令输入后,django把自带的表和我们设置的表都创建成功了。我们在pycharm里面看看。

image-20201108183927699

可以看到创建成功了。

配置路由

数据库模型建设完成了,按理说我们应该进入视图的开发了,但是先别着急,我们先定义一下url的规则。

我们打开django的urls.py文件,进行配置。

userapi/urls.py

from django.contrib import admin
from django.urls import path
from usermanage import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('user/', views.UsersView.as_view()),
    path('user/<int:pk>/', views.UsersView.as_view())
]

我们先从usermanage用户管理app中导入视图模块,然后配置user/路由作为本次的访问路径。

路由配置完成了。那我们先来编写一个访问视图吧。

视图开发

GET

在开发之前我们应该先分析一下需求,我们要实现什么样的效果

  • 首先http://127.0.0.1:8000/user/get方法应该可以访问全部的用户
  • 然后http://127.0.0.1:8000/user/1/get方法应该可以访问单个用户
  • http://127.0.0.1:8000/user/?name=XX/get方法应该可以过滤出符合条件的用户

好了明确了需求我们就进入开发吧。代码如下:

import json
from django.http import JsonResponse
from django.views.generic import View
from django.forms.models import model_to_dict

from .models import Users


class UsersView(View):
    
    def get(self, request, pk=0):
        if pk:
            try:
                user = Users.objects.get(pk=pk)
                user = model_to_dict(user)
                return JsonResponse({'code': 200, 'message': 'success', 'data': user}, status=200)
            except Users.DoesNotExist:
                return JsonResponse({'code': 404, 'message': '用户不存在'}, status=200)
        data = json.loads(request.body) if request.body else {}
        users = list(Users.objects.filter(**data).all().values())
        return JsonResponse({'code': 200, 'message': 'success', 'data': users}, status=200)

通过pk参数区分是单个用户还是多个用户。

然后通过request的请求来过滤对应的数据。

然后我们测试一下。启动我们的django,和上面的启动方法一样。

使用postman测试接口

image-20201108185919940

请求的方法和地址没问题,响应是200,但是没有数据。因为我们还没有创建数据。

我们先来创建一个数据吧,在那创建呢,那肯定是django的管理后台了。

我们先来创建一个超级用户吧。

image-20201108190558793

创建成功后我们先设置一下django的管理后台的东西。

usermanage/admin.py

from django.contrib import admin
from .models import Users


# Register your models here.

@admin.register(Users)
class UsersAdmin(admin.ModelAdmin):
    list_display = ('name', 'sex', 'idcard', 'address', 'company', 'created_time')

然后我们打开管理后台在里面创建一个数据吧。

image-20201108190922032

创建成功后我们再来访问刚才那个接口:

image-20201108190950219

可以看到有数据了,就是我们刚才创建的那条。然后我们验证一下我们的需求。

image-20201108202605025

到这里呢 get方法的内容就开发完了,接下来我们要开发post请求了。

POST

分析一下post请求,我们post请求是添加一条数据。根据restful的规范添加数据的同时我们必须要返回该请求的信息。

那么一起来看看吧

import json

from django.forms.models import model_to_dict
from django.views.generic import View
from django.http import JsonResponse
from django.db.utils import IntegrityError
from .models import Users

class UsersView(View):
    
    ...
    
    def post(self, request):
        data = json.loads(request.body)
        try:
            user = Users.objects.create(**data)
            user = model_to_dict(user)
	    return JsonResponse({'code': 201, 'message': 'created', 'data': user}, status=201)
        except IntegrityError:
            return JsonResponse({'code': 400, 'message': '身份证号码已存在!'}, status=200)

好了,代码我们写完了,我们在postman中测试一下。

image-20201108203504351

什么情况,报错了,我们在浏览器里面看看。

那么这个是csrf验证失败,什么是csrf呢?看看度娘怎么说吧跨站请求伪造(英语:Cross-site request forgery)

知道了是什么那么怎么处理呢,django内置了一个方法,我们只需要添加上就行了。更改代码

from django.views.decorators.csrf import csrf_exempt


# Create your views here.
class UsersView(View):
    @csrf_exempt
    def dispatch(self, request, *args, **kwargs):
        return super(UsersView, self).dispatch(request, *args, **kwargs)

	...
    
    def post(self, request):
        data = json.loads(request.body)
        try:
            user = Users.objects.create(**data)
        except IntegrityError:
            return JsonResponse({'code': 400, 'message': '身份证号码已存在!'}, status=200)
        user = model_to_dict(user)
        return JsonResponse({'code': 201, 'message': 'created', 'data': user}, status=201)

使用csrf_exempt装饰器给dispatch就可以了。我们再来测试一下。

image-20201108203122145

可以看到我们在postman中发送请求之后,该条信息被成功的创建了。并且返回了201的状态码。

PUT

更新一条数据。这个应该不用细说了,直接看代码吧。

    def put(self, request, pk=0):
        data = json.loads(request.body)
        user = Users.objects.get(pk=pk)
        for key, value in data.items():
            setattr(user, key, value)
        user.save()
        user = model_to_dict(user)
        return JsonResponse({'code': 200, 'message': 'updated', 'data': user}, status=200)

用postman测试一下。

image-20201108205918958

可以看到更新成功了。

DELETE

删除一条数据,删除数据和更新数据一样,都需要指定具体的数据,避免胡删除。

    def delete(self, request, pk=0):
        user = Users.objects.get(pk=pk)
        user.delete()
        return JsonResponse({'code': 204, 'message': 'deleted'}, status=204)

使用postman测试一下。

image-20201108210255488

可以看到成功删除了。因为我刚才把两个都删除了。我们重新请求一下全部的数据。

image-20201108210450312

本篇的代码片段就到此结束了。

后记

django里面的东西太多,基础差,学起来很费劲,这篇就做个临时的记录把。以后回顾的时候有东西参考。

原文地址:https://www.cnblogs.com/wxhou/p/django-restful-userapi.html