天天看點

Django之開發restful接口

 django中的開發接口有兩種模式FBV和CBV,分别是

基于函數視圖

基于類視圖

,詳細的可以看看菜鳥教程的Django 視圖 - FBV 與 CBV,由于本文的使用者管理是一個restful風格的api,是以我選擇的是類視圖的開發風格。

簡單使用者model:

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 = '使用者管理'      

配置路由:

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方法應該可以過濾出符合條件的使用者

則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的請求來過濾對應的資料

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)      

 一般會遇到通路問題:

Django之開發restful接口

那麼這個是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就可以了。

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)      

DELETE:

删除一條資料,删除資料和更新資料一樣,都需要指定具體的資料,避免胡删除。

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