import uuid from django.core.files import File from django.http import JsonResponse, Http404, HttpResponse from django.shortcuts import render, redirect from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage from .form import RegisterForm, LoginForm, CreateForm, AnswerForm from .models import CyberUser, Question, Choice from django.contrib.auth import authenticate, login, logout from django.contrib.auth.decorators import login_required from PIL import Image from io import BytesIO def compress_image(file_obj, max_size_bytes=1 * 1024 * 1024): # 从文件对象读取数据并创建Image对象 img = Image.open(file_obj) # 创建一个BytesIO对象来保存压缩后的WebP数据 output_buffer = BytesIO() quality = 85 while True: try: img.save(output_buffer, 'webp', quality=quality) except Exception as e: print(f"Error saving image as WebP: {e}") return None output_buffer.seek(0) new_size = len(output_buffer.read()) # 如果新的大小小于或等于5MB,则退出循环 if new_size <= max_size_bytes: break # 如果新的大小大于5MB,降低质量并重试 quality -= 5 if quality < 1: print("Unable to compress the image to 5MB or less.") return None output_buffer.seek(0) return output_buffer def home(request): content = {'user': request.user} return render(request, 'home.html', content) def about(request): return HttpResponse("尚未完成") @login_required(login_url='/exam/login') def history(request): page_size = 10 user = request.user questions = Question.objects.filter(choice__user=user) paginator = Paginator(questions, page_size) page = request.GET.get('page', 1) try: # 尝试获取当前页的记录 question = paginator.page(page) except PageNotAnInteger: question = paginator.page(1) except EmptyPage: question = paginator.page(paginator.num_pages) context = {'questions': question, 'page': paginator.page(page), 'paginator': paginator} return render(request, 'history.html', context) @login_required(login_url='/exam/login') def history_detail(request): questionID = request.GET.get('question') user = request.user if questionID: question = Question.objects.get(uid=questionID) if question is None: return Http404 choice = Choice.objects.get(question=question,user=user) if choice is None: return Http404 context = { 'question': question, 'choice': choice, 'user': user, 'forward_url': request.META.get('HTTP_REFERER', '/'), } return render(request, 'history_detail.html', context) else: return Http404 def register(request): if request.method == 'GET': if request.user.is_active: return redirect("/exam/") return render(request, 'register.html', {'form': RegisterForm()}) elif request.method == 'POST': if request.user.is_active: return JsonResponse({ 'code': 200, 'message': '已经登陆', 'data': 'failed', }) form = RegisterForm(request.POST) if form.is_valid(): username = form.cleaned_data['username'] nickname = form.cleaned_data['nickname'] password = form.cleaned_data['password1'] email = form.cleaned_data['email'] username_exist = CyberUser.objects.filter(username=username).exists() if username_exist: return JsonResponse({"code": 400, "message": "验证失败", "data": {"username": "", "password1": "", "password2": "", "email": "", }, }) CyberUser.objects.create_user( username=username, nickname=nickname, password=password, email=email, ) return JsonResponse({"code": 200, "message": "验证通过,已注册", "data": {"username": "", "password1": "", "password2": "", "email": "", }, }) else: return JsonResponse({"code": 400, "message": "验证失败", "data": {"username": form.errors.get("username"), "password1": form.errors.get("password1"), "password2": form.errors.get("password2"), "email": form.errors.get("email"), "nickname": form.errors.get("nickname")}}) else: raise Http404 def login_view(request): if request.method == 'GET': if request.user.is_active: return redirect("/exam/") return render(request, 'login.html', {'form': LoginForm()}) elif request.method == 'POST': if request.user.is_active: return JsonResponse( { 'code': 200, 'message': '已经登陆', 'data': 'abort', } ) form = LoginForm(request.POST) if form.is_valid(): username = form.cleaned_data['username'] password = form.cleaned_data['password'] user = authenticate(request, username=username, password=password) if user and user.is_active: login(request, user) request.session['username'] = username request.session.set_expiry(1800) return JsonResponse( { "code": 200, "message": '登陆成功', "data": username, } ) elif user and user.is_active: return JsonResponse( { "code": 400, "message": "用户状态错误,请联系管理员修正", "data": "user is not active", } ) else: return JsonResponse( { "code": 400, "message": "用户名或密码错误", "data": None, } ) else: return JsonResponse( { "code": 400, "message": "验证失败,用户名或密码格式错误", "data": form.errors.get(), } ) else: raise Http404 def logout_view(request): logout(request) return redirect('/exam/login') @login_required(login_url='/exam/login') def create_question(request): if request.method == 'GET': return render(request, 'create.html', {'form': CreateForm}) elif request.method == 'POST': form = CreateForm(request.POST, request.FILES) if form.is_valid(): text = form.cleaned_data['text'] image = form.cleaned_data['image'] a = form.cleaned_data['a'] b = form.cleaned_data['b'] c = form.cleaned_data['c'] d = form.cleaned_data['d'] answer = form.cleaned_data['answer'] new_question = Question( question_text=text, choice_a=a, choice_b=b, choice_c=c, choice_d=d, answer=answer, ) if image: image = compress_image(image) new_question.image = File(image, name=f'{str(uuid.uuid4())}.webp') new_question.save() return JsonResponse( { 'code': 200, 'message': 'success', 'data': '', } ) else: return JsonResponse( { 'code': 400, 'message': '参数不正确', 'data': form.errors } ) @login_required(login_url='/exam/login') def get_question(request): user = request.user question = Question.objects.exclude(choice__user=user).order_by('?').first() return render(request, "question.html", {'question': question, 'form': AnswerForm, 'user': request.user}) @login_required(login_url='/exam/login') def answer(request): if request.method == 'POST': form = AnswerForm(request.POST) if form.is_valid(): user = request.user user_ans = form.cleaned_data['answer'] questionID = form.cleaned_data['questionID'] question = Question.objects.get(uid=questionID) if Choice.objects.filter(user=user, question=question).exists(): return JsonResponse( { 'code': 200, 'message': '该问题已经回答过了', 'data': '', } ) choice = Choice(user=user, question=question, choice=user_ans) choice.save() if user_ans == question.answer: user.score = user.score + 1 user.save() return JsonResponse( { 'code': 200, 'message': 'success', 'data': { 'correction': user_ans == question.answer, 'answer': question.answer, }, } ) else: return JsonResponse( { 'code': 400, 'message': '参数错误', 'data': '表单不可用', } ) else: return Http404