rest api

Bobbyby發表於2018-06-07

Api 介面 高山山書寫例子

  • resources.py

    #!coding=utf-8
    import json
    
    from django.http.response import HttpResponse
    from django.conf.urls import url
    from django.views.decorators.csrf import csrf_exempt
    
    from Api.utils import method_not_allowed
    
    # 為所有的請求 規定一個預設類 方便 且 節省程式碼量 不用每次判斷method
    class Resource(object):
        def __init__(self, name=None):
            # 給 resource 初始名字   如果沒有輸入name  那麼初始名為自己的類名
            self.name = name or self.__class__.__name__.lower()
    
        def enter(self, request, *args, **kwargs):
            method = request.method
            #判斷request的型別是什麼,分別進行處理
            if method == 'GET':
                response = self.get(request, *args, **kwargs)
            elif method == 'POST':
                response = self.post(request, *args, **kwargs)
            elif method == 'PUT':
                response = self.put(request, *args, **kwargs)
            elif method == 'DELETE':
                response = self.delete(request, *args, **kwargs)
            elif method == 'HEAD':
                response = self.head(request, *args, **kwargs)
            elif method == "OPTIONS":
                response = self.options(request, *args, **kwargs)
            else:
                response = HttpResponse(json.dumps({
                    "state": 422,
                    "msg": '方法不支援'
                }))
            return response
      # 因為是預設的resources類裡的方法  預設都是返回方法不支援
        def get(self, request, *args, **kwargs):
            return method_not_allowed()   # method_not_allowed 這類經常用到的函式 可以放在一個py檔案裡 此例子是放在utils.py檔案中
    
        def post(self, request, *args, **kwargs):
            return method_not_allowed()
    
        def delete(self, request, *args, **kwargs):
            return method_not_allowed()
    
        def put(self, request, *args, **kwargs):
            return method_not_allowed()
    
        def options(self, request, *args, **kwargs):
            return method_not_allowed()
    
        def head(self, request, *args, **kwargs):
            return method_not_allowed()
    
    # url註冊器  register方法將檢視類   
    class Register(object):
    
        def __init__(self, version='v1'):
            self.version = version
            self.resources = []
    
        def regist(self, resource):
            self.resources.append(resource)
      
        @property    # property裝飾器  可以使函式 通過 register.urls 來獲得函式的返回值
        def urls(self):
            urlpatterns = []
            for resource in self.resources:
                urlpatterns.append(
                    url(r'{version}/{name}'.format(version=self.version,
                                                   name=resource.name), csrf_exempt(resource.enter))  #csrf_exempt()裝飾器  是為了使enter方法可以不被csrf限制
                )
            return urlpatterns  
    
    
    • views.py

      #!coding=utf-8
      
      import random
      
      from datetime import datetime
      
      from django.contrib.auth import authenticate, login, logout
      
      from Question.models import *
      
      from Api.resources import Resource
      
      from Api.utils import *
      
      from Api.decorators import *
      
      #以下均為檢視的類方法  繼承上面的Resource類  只需要寫自己需要的方法  不需要寫那些限制的重複程式碼
      
      #由於瀏覽器只有get和post兩種方式  且django框架只能解析form-data,  json,xml,text均無法自動解析 因此寫一箇中介軟體  用來偽增加瀏覽器的請求方式(實際上還是隻有兩種請求方式), 並對返回的不同格式的資料進行提取解析, 方便在檢視檔案中進行操作
      
      獲取註冊碼
      
      class ReigstCodeResource(Resource):
      
          def get(self, request, *args, **kwargs):
      
              regist_code = random.randint(10000, 100000)
      
              request.session['regist_code'] = regist_code
      
              return HttpResponse(json.dumps({
      
                  'regist_code': regist_code
      
              }), content_type="application/json")
      
      使用者資訊
      
      class UserResource(Resource):
      
          # 獲取使用者資訊
      
          def get(self, request, *args, **kwargs):
      
              if request.user.is_authenticated:
      
                  user = request.user
      
                  # 判斷是否是普通使用者
      
                  if hasattr(user, 'userinfo'):
      
                      userinfo = user.userinfo
      
                      # 構建json字典
      
                      data = dict()
      
                      data['user'] = user.id
      
                      data['age'] = getattr(userinfo, 'age', '')
      
                      data['name'] = getattr(userinfo, 'name', '')
      
                      data['gender'] = getattr(userinfo, 'gender', '')
      
                      data['phone'] = getattr(userinfo, 'phone', '')
      
                      data['email'] = getattr(userinfo, 'email', '')
      
                      data['address'] = getattr(userinfo, 'address', '')
      
                      if userinfo.birthday:
      
                          data['birthday'] = userinfo.birthday.strftime("%Y-%m-%d")
      
                      else:
      
                          data['birthday'] = datetime.now().strftime("%Y-%m-%d")
      
                      data['qq'] = getattr(userinfo, 'qq', '')
      
                      data['wechat'] = getattr(userinfo, 'wechat', '')
      
                      data['job'] = getattr(userinfo, 'job', '')
      
                      data['salary'] = getattr(userinfo, 'salary', '')
      
                      # 用json把data轉化成字串,返回給客戶端
      
                      return HttpResponse(json.dumps(data), content_type="application/json")
      
                  # 判斷是否是客戶
      
                  elif hasattr(user, 'customer'):
      
                      customer = user.customer
      
                      # 構建json字典
      
                      data = dict()
      
                      data['user'] = user.id
      
                      data['name'] = getattr(customer, 'name', '')
      
                      data['email'] = getattr(customer, 'email', '')
      
                      data['company'] = getattr(customer, 'company', '')
      
                      data['address'] = getattr(customer, 'address', '')
      
                      data['phone'] = getattr(customer, 'phone', '')
      
                      data['mobile'] = getattr(customer, 'mobile', '')
      
                      data['qq'] = getattr(customer, 'qq', '')
      
                      data['wechat'] = getattr(customer, 'wechat', '')
      
                      data['web'] = getattr(customer, 'web', '')
      
                      data['industry'] = getattr(customer, 'industry', '')
      
                      data['description'] = getattr(customer, 'description', '')
      
                      # 用json把data轉化稱字串,返回給客戶端
      
                      return HttpResponse(json.dumps(data), content_type="application/json")
      
                  else:
      
                      # 沒有相關使用者資訊,返回空
      
                      return HttpResponse(json.dumps({
      
                          "data": {}
      
                      }), content_type="application/json")
      
              # 使用者未登入,不允許檢視資訊
      
              return HttpResponse(json.dumps({
      
                  "msg": '未登入'
      
              }), content_type="application/json")
      
      
  # 註冊使用者
  def put(self, request, *args, **kwargs):
      data = request.PUT
      username = data.get('username', '')
      password = data.get('password', '')
      regist_code = data.get('regist_code', '')
      session_regist_code = request.session.get('regist_code', '')
      category = data.get('category', 'userinfo')
      ensure_password = data.get('ensure_password', '')
  
      # 構建錯誤資訊字典
      errors = dict()
      if not username:
          errors['username'] = '沒有提供使用者名稱'
      elif User.objects.filter(username=username):
          errors['username'] = '使用者名稱已存在'
      if len(password) < 6:
          errors['password'] = '密碼長度不夠'
      if password != ensure_password:
          errors['ensure_password'] = '密碼不一樣'
      if regist_code != str(session_regist_code):
          errors['regist_code'] = '驗證碼不對'
      if errors:
          return HttpResponse(json.dumps(errors), content_type='application/json')
      user = User()
      user.username = username
      # 設定密碼
      user.set_password(password)
      user.save()
      # 根據使用者型別,建立普通使用者或者客戶
      if category == 'userinfo':
          userinfo = UserInfo()
          userinfo.user = user
          userinfo.name = '姓名'
          userinfo.save()
      else:
          customer = Customer()
          customer.name = '客戶名稱'
          customer.user = user
          customer.save()
  
      return HttpResponse(json.dumps({
          "msg": "建立成功",
          "user_id": user.id
      }), content_type='application/json')
  
  # 更新使用者
  def post(self, request, *args, **kwargs):
      data = request.POST
      user = request.user
      if user.is_authenticated:
          # 判斷是否是普通使用者
          if hasattr(user, 'userinfo'):
              userinfo = user.userinfo
              userinfo.name = data.get('name', '姓名')
              userinfo.age = data.get('age', '')
              userinfo.gender = data.get('gender', '')
              userinfo.phone = data.get('phone', '')
              userinfo.email = data.get('email', '')
              userinfo.address = data.get('address', '')
  
              # 時間特殊處理
              try:
                  birthday = datetime.strptime(
                      data.get('birthday', '2018-01-01'), "%Y-%m-%d")
              except Exception as e:
                  birthday = datetime.now()
  
              userinfo.birthday = birthday
  
              userinfo.qq = data.get('qq', '')
              userinfo.wechat = data.get('wechat', '')
              userinfo.job = data.get('job', '')
              userinfo.salary = data.get('salary', '')
              userinfo.save()
          # 判斷是否是客戶
          elif hasattr(user, 'customer'):
              customer = user.customer
              customer.name = data.get('name', '客戶名稱')
              customer.email = data.get('email', '')
              customer.company = data.get('company', '')
              customer.address = data.get('address', '')
              customer.phone = data.get('phone', '')
              customer.mobile = data.get('mobile', '')
              customer.qq = data.get('qq', '')
              customer.wechat = data.get('wechat', '')
              customer.web = data.get('web', '')
              customer.industry = data.get('industry', '')
              customer.description = data.get('description', '')
              customer.save()
          return HttpResponse(json.dumps({
              'msg': '更新成功'
          }), content_type="application/json")
      return HttpResponse(json.dumps({
          'msg': '還未登入'
      }), content_type="application/json")

使用者登入與退出

class SessionResource(Resource):

  def get(self, request, *args, **kwargs):
      if request.user.is_authenticated:
          return json_response({
              'msg': '已經登入'
          })
      return json_response({
          'msg': '還未登入'
      })
  
  def put(self, request, *args, **kwargs):
      data = request.PUT
      username = data.get('username', '')
      password = data.get('password', '')
      user = authenticate(username=username, password=password)
      if user:
          login(request, user)
          return json_response({
              'msg': '登入成功'
          })
      return json_response({
          'msg': '使用者名稱或密碼錯誤'
      })
  
  def delete(self, request, *args, **kwargs):
      logout(request)
      return json_response({
          'msg': '退出成功'
      })

問卷資源

class QuestionnaireResource(Resource):

@customer_required
def get(self, request, *args, **kwargs):
return json_response({})

  @customer_required
  def put(self, request, *args, **kwargs):
      return json_response({})


  @customer_required
  def post(self, request, *args, **kwargs):
      return json_response({})
  
  @customer_required
  def delete(self, request, *args, **kwargs):
      return json_response({})

​```
  
​```
  • middleware.py 中介軟體

    import json
    
    from django.http.multipartparser import MultiPartParser
    from django.middleware.common import MiddlewareMixin
    
    
    class DataConvert(MiddlewareMixin):
        """
        # 資料型別轉換
        > 因為django只能解析使用post方式上傳的formdata
        > 不能夠解析通過其他方法上傳的json,xml,text格式資料,所以這裡面,我們需要手動來解析上傳的資料
        """
    
        def process_request(self, request):
            method = request.method
            if 'application/json' in request.META['CONTENT_TYPE']:
                # 把客戶端上傳的json資料轉化成python字典
                data = json.loads(request.body.decode())
                files = None
            elif 'multipart/form-data' in request.META['CONTENT_TYPE']:
                # 把客戶端已formdata上傳的資料進行解析,通常客戶端會把上傳的檔案也放在formdata中,
                # 所以下面的解析會把上傳的檔案也解析出來
                data, files = MultiPartParser(
                    request.META, request, request.upload_handlers).parse()
            else:
                data = request.GET
                files = None
    
            if 'HTTP_X_METHOD' in request.META:
                method = request.META['HTTP_X_METHOD'].upper()
                setattr(request, 'method', method)
    
            if files:
                setattr(request, '{method}_FILES'.format(method=method), files)
            setattr(request, method, data)
    
  • decorators.py 裝飾器

    from Api.utils import permission_denied
    
    #因為檢視檔案中  很多函式需要加使用者驗證  使用裝飾器 減少程式碼量
    # 在執行制定方法前, 先對使用者進行判斷  是否已經登陸, 並對其進行分類處理
    def customer_required(func):
        def _wrapper(self, request, *args, **kwargs):
            if request.user.is_authenticated and hasattr(request.user, 'customer'):
                return func(self, request, *args, **kwargs)
            return permission_denied()
        return _wrapper
    
    
    def userinfo_required(func):
        def _wrapper(self, request, *args, **kwargs):
            if request.user.is_authenticated and hasattr(request.user, 'userinfo'):
                return func(self, request, *args, **kwargs)
            return permission_denied()
        return _wrapper
    
    
  • utils.py 一些常見的response放在這個檔案中

    #!coding=utf-8
    import json
    
    from django.http.response import HttpResponse
    
    
    def method_not_allowed():
        return HttpResponse(json.dumps({
            "state": 405,
            "msg": '方法不支援',
        }), content_type="application/json")
    
    
    def json_response(data):
        json_data = {
            'state': 200,
            'msg': 'OK',
            'data': data
        }
        return HttpResponse(json.dumps(json_data), content_type='application/json')
    
    
    def server_error():
        return HttpResponse(json.dumps({
            'state': 500,
            'msg': '伺服器發生錯誤'
        }), content_type='application/json')
    
    
    def not_found():
        return HttpResponse(json.dumps({
            'state': 404,
            'msg': '沒有找到頁面'
        }), content_type='application/json')
    
    
    def params_error(data={}):
        return HttpResponse(json.dumps({
            'state': 422,
            'msg': '引數錯誤',
            'data': data
        }), content_type='application/json')
    
    
    def not_authenticated():
        return HttpResponse(json.dumps({
            'state': 401,
            'msg': '未登入'
        }), content_type='application/json')
    
    
    def permission_denied():
        return HttpResponse(json.dumps({
            'state': 403,
            'msg': '沒有許可權'
        }), content_type='application/json')
    
    

相關文章