zoukankan      html  css  js  c++  java
  • 中间件作业

    1. 用ajax提交一个json格式数据,再返回一个json数据,用console.log打印出

      views.py

      def test(request):
          back_dict = {}
          if request.method == 'POST':
              back_dict['info'] = json.dumps(request.data)
              return JsonResponse(back_dict)
          return render(request, 'test.html', locals())
      

      ajax

      <script>
          $('#id_submit').on('click', function () {
              $.ajax({
                  url: '',
                  type: 'post',
                  headers: {'X-CSRFToken': '{{ csrf_token }}'},
                  data: JSON.stringify({"username": $('#id_username').val(), "password": $('#id_password').val()}),
                  contentType: 'application/json',
                  success: function (args) {
                      console.log(args.info);
                      console.log(typeof args.info);
                  }
              })
          })
      </script>
      

      自定义中间件(处理json格式的数据)

      from django.utils.deprecation import MiddlewareMixin
      import json
      
      
      class JsonDataProcess(MiddlewareMixin):
          def process_request(self, request):
              self.data = {}
              if request.method == 'POST':
                  if request.META['CONTENT_TYPE'].split(';')[0] == 'application/json':
                      self.data.update(json.loads(request.body))
              request.data = self.data
      
    2. 通过ajax来上传文件

      views.py

      def upload_avatar(request):
          if request.method == 'POST':
              back_dict = {'code': 1001}
              if not request.avatar:
                  back_dict['code'] = 1002
              else:
                  back_dict['avatar_name'] = request.avatar.get('name')
              return JsonResponse(back_dict)
          return render(request, 'avatar.html', locals())
      

      js

      <script>
          $('#id_avatar').on('change', function () {
              let fileReaderObj = new FileReader();
              let avatarObj = $(this)[0].files[0];
              fileReaderObj.readAsDataURL(avatarObj); //异步操作
              fileReaderObj.onload = function () {
                  $('#image').attr('src', fileReaderObj.result)
              }
          });
          $('#id_upload').on('click', function () {
              let formDataObj = new FormData();
              formDataObj.append('avatar', $('#id_avatar')[0].files[0]);
              //发送ajax请求
              $.ajax({
                  url: '',
                  type: 'post',
                  headers: {'X-CSRFToken': '{{ csrf_token }}'},
                  contentType: false,
                  processData: false,
                  data: formDataObj,
                  success: function (args) {
                      if (args.code === 1001) {
                          swal({
                              title: args.avatar_name + ' upload success',
                              type: 'success',
                              confirmButtonText: 'ok',
                              closeOnConfirm: false,
                          })
                      } else {
                          swal({
                              title: 'upload fail',
                              type: 'error',
                              confirmButtonText: 'ok',
                              closeOnConfirm: false,
                          })
                      }
                  }
              })
          })
      </script>
      

      中间件(存储上传的文件)

      from django.utils.deprecation import MiddlewareMixin
      
      
      class FileStore(MiddlewareMixin):
          def process_request(self, request):
              self.avatar_info = {}
              if request.method == 'POST':
                  if request.FILES:
                      avatar = request.FILES.get('avatar')
                      self.avatar_info.update({"name": avatar.name, "size": avatar.size})
                      with open(f'media/{avatar.name}', mode='wb') as f:
                          for chunk in avatar.chunks():
                              f.write(chunk)
              request.avatar = self.avatar_info
      

      上传文件的配置(media)

      # settings.py
      MEDIA_URL = '/media/'
      MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
      
      # urls.py
      from django.views.static import serve
      from pratice04 import settings
          # 暴露后端的文件资源
          url(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}),
      
    3. 用ajax完成用户的注册

      具体需求

      注册的信息包括如下:
      {'username':'xxx','pwd':'xxx','re_pwd':'xxx','age':18,'gender':'male','avatar':'xxx.jpg'}
      使用form组件来做认证:
      < username:>
      (1)用户名必须包括数字,字母,以及{!@#$%^&*}等特殊字符组成;
      (2)用户名为4-16位;
      (3)用户名不能以(sb)开头或结尾;
      (4)不能注册重复的用户
       <password:>
      (1)密码为4-16位;
      < re_password:>
       re_password和password必须一致
      < age:>
      (1)18<age<120
      

      views.py

      def register(request):
          if request.method == 'POST':
              back_dict = {'code': 1200}
              user_info = {
                  'gender': request.POST.get('gender'),
                  'avatar': request.FILES.get('avatar'),
              }
              print(request.POST)
              form_obj = RegForm(request.POST)
              if form_obj.is_valid():
                  user_info.update(form_obj.cleaned_data)
                  models.User.objects.create(**user_info)
              else:
                  back_dict['code'] = 1201
                  back_dict['error_msgs'] = form_obj.errors
              return JsonResponse(back_dict)
          return render(request, 'register.html', locals())
      

      forms.py

      def register(request):
          if request.method == 'POST':
              back_dict = {'code': 1200}
              user_info = {
                  'gender': request.POST.get('gender'),
                  'avatar': request.FILES.get('avatar'),
              }
              print(request.POST)
              form_obj = RegForm(request.POST)
              if form_obj.is_valid():
                  user_info.update(form_obj.cleaned_data)
                  models.User.objects.create(**user_info)
              else:
                  back_dict['code'] = 1201
                  back_dict['error_msgs'] = form_obj.errors
              return JsonResponse(back_dict)
          return render(request, 'register.html', locals())
      

      models.py

      from django.db import models
      import uuid,os
      
      # Create your models here.
      
      GENDER_CHOICE = (
          (0, 'male'),
          (1, 'female'),
          (2, 'secret')
      )
      
      
      def path_and_rename(instance, filename):
          """
          uplaod_to: 上传文件的路径
          ext:       文件的后缀名,如'jpg'
          """
          upload_to = 'avatar'
          ext = filename.split('.')[-1]
          filename = f'{uuid.uuid4().hex[:16]}.{ext}'  # 截取16位的uuid码作为文件名称
          return os.path.join(upload_to, filename)
      
      
      class User(models.Model):
          username = models.CharField(max_length=16, verbose_name='用户名')
          password = models.CharField(max_length=16, verbose_name='密码')
          re_password = models.CharField(max_length=16, verbose_name='确认密码')
          age = models.IntegerField(verbose_name='年龄')
          gender = models.IntegerField(verbose_name='性别', choices=GENDER_CHOICE, default=0)
          avatar = models.ImageField(upload_to=path_and_rename, verbose_name='用户头像')
      
          def __str__(self):
              return self.username
      
          class Meta:
              verbose_name_plural = '用户表'
      

      js

      <script>
          $('#id_avatar').on('change', function () {
              let fileReaderObj = new FileReader();
              let fileObj = $(this)[0].files[0];
              fileReaderObj.readAsDataURL(fileObj); //异步操作
              fileReaderObj.onload = function () {
                  $('#id_img').attr('src', fileReaderObj.result);
              }
          });
          $('#id_register').on('click', function () {
              let formDataObj = new FormData();
              formDataObj.append('username', $('#id_username').val());
              formDataObj.append('password', $('#id_password').val());
              formDataObj.append('re_password', $('#id_re_password').val());
              formDataObj.append('age', $('#id_age').val());
              formDataObj.append('gender', $('#id_gender').val());
              formDataObj.append('avatar', $('#id_avatar')[0].files[0]);
              console.log(formDataObj);
              //发送ajax请求
              $.ajax({
                  url: '',
                  type: 'post',
                  headers: {'X-CSRFToken': '{{ csrf_token }}'},
                  data: formDataObj,
                  contentType: false,
                  processData: false,
                  success: function (args) {
                      if (args.code === 1200) {
                          swal({
                              title: 'register success',
                              type: 'success',
                              confirmButtonText: 'ok',
                              closeOnConfirm: false,
                          })
                      } else if (args.code === 1201) {
                          //将错误的提示信息进行一一的展示
                          $.each(args.error_msgs, function (field, errors) {
                              $(`#id_${field}`).next().children().text(errors[0]).parent().parent().addClass('has-error')
                          })
                      }
                  }
              })
          });
          $('input').on('focus', function () {
              $(this).next().children().text('').parent().parent().removeClass('has-error')
          });
      </script>
      
    4. 自己手动实现一个存文件的session,自定制一个session字典

      自定义session的思路

      # 当请求来的时候
      (1)生成一个空的 IdentityDict(request.Identity = IdentityDict());
      (2)放行的URL ---> ['/index/','/login/','/register/']
      (3)如果有随机字符串,则根据随机字符串查询Identity表,将Identity_data赋值给request.Identity,如果没有随机字符串,则重定
      return redirect(f'/login/?next={request.path}')
      
      # 当请求走的时候
      判断对于Identity的操作方式是,更新(modified),删除( deleted),还是什么都不做,如果什么都不做,直接放行
      # 更新操作
      (1)生成一个随机字符串
      (2)跟新Identity表
      (3)将随机字符串赋值给Cookie
      # 删除操作
      (1)根据随机字符串,删除数据库中的记录
      (2)删除cookie
      (3)重定向
      

      需要注意以下的几点:

      (1)每个request请求之间是相互独立的,即request.Identity独立
      (2)设置request.Identity属性时,需要考虑请求方式,否则会出现request没有Identity属性
      

      Identity.py

      class Identity(models.Model):
          identity_key = models.CharField(max_length=64, primary_key=True)
          identity_data = models.CharField(max_length=128)
      

      views.py

      def login(request):
          if request.method == 'POST':
              back_dict = {'code': 1300}
              username = request.POST.get('username')
              password = request.POST.get('password')
              next_url = request.GET.get('url')
              user_obj = models.User.objects.filter(
                  username=username,
                  password=password
              ).first()
              if not user_obj:
                  back_dict['code'] = 1301
                  back_dict['msg'] = '用户名或者密码错误'
              else:
                  if next_url:
                      back_dict['url'] = next_url
                  request.Identity.modified = True
              return JsonResponse(back_dict)
          return render(request, 'login.html', locals())
      

      中间件

      from django.utils.deprecation import MiddlewareMixin
      from app01.middlewareitem.utils.sessiondict import IdentityDict
      from app01.middlewareitem.utils.encrypt import hash256_encrypt, md5_encrypt
      from app01 import models
      from django.shortcuts import redirect
      
      import json
      import uuid
      
      NO_IDENTITY_URL = ['/login/', '/index/', '/register/']
      
      
      class IdentityMiddleware(MiddlewareMixin):
      
          @property
          def random_str(self):
              return md5_encrypt(str(uuid.uuid4()))
      
          def process_request(self, request):
              request.Identity = IdentityDict()
              if request.path not in NO_IDENTITY_URL:
                  random_str = request.COOKIES.get('identity_id')
                  if not random_str:
                      return redirect(f'/login/?next={request.path}')
                  identity_obj = models.Identity.objects.get(identity_key=random_str)
                  request.Identity.identity_data = identity_obj.identity_data
      
          def process_response(self, request, response):
              if request.Identity.modified:
                  request.Identity.identity_key = self.random_str
                  request.Identity['identity_data'] = hash256_encrypt(
                      json.dumps({
                          'username': request.POST.get('username'),
                          'password': request.POST.get('password'),
                      })
                  )
                  models.Identity.objects.create(
                      identity_key=request.Identity.identity_key,
                      identity_data=request.Identity.identity_data,
                  )
                  response.set_cookie('identity_id', request.Identity.identity_key)
              if request.Identity.deleted:
                  random_str = request.COOKIES.get('identity_id')
                  models.Identity.objects.filter(identity_key=random_str).delete()
                  response.delete_cookie('identity_id')
              return response
      
      

      IdentityDict

      class IdentityDict(dict):
          def __init__(self, *args, **kwargs):
              super(IdentityDict, self).__init__(*args, **kwargs)
              self.modified = False
              self.deleted = False
      
          @staticmethod
          def check_type_of_key(key):
              return isinstance(key, str) or False
      
          def __setattr__(self, key, value):
              if not self.check_type_of_key(key):
                  raise TypeError(
                      "The type of key must be 'str' "
                  )
              if key not in ['modified', 'deleted']:
                  self['modified'] = True
              super(IdentityDict, self).__setattr__(key, value)
      
          def __getattr__(self, item):
              return self.__dict__.get(item)
      
          def __setitem__(self, key, value):
              if not self.check_type_of_key(key):
                  raise TypeError(
                      "The type of key must be 'str' "
                  )
              if key not in ['modified', 'deleted']:
                  self.modified = True
              setattr(self, key, value)
      
          def __getitem__(self, item):
              return getattr(self, item, None)
      
          def flush(self):
              self.deleted = True
      
  • 相关阅读:
    html +JS 自学
    Linux下SVN多版本库管理
    Jenkins更换国内源
    Kubernetes Service
    Kubernetes Pod
    ubuntu下vim配置日常工作版本
    PYTHON替代MATLAB在线性代数学习中的应用(使用Python辅助MIT 18.06 Linear Algebra学习)
    mongodb 片键需要思考的问题
    SpringBoot--Easycode插件自定义模板
    Docker-概述
  • 原文地址:https://www.cnblogs.com/surpass123/p/13235882.html
Copyright © 2011-2022 走看看