-
用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
-
通过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}),
-
用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>
-
自己手动实现一个存文件的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