CyberExam-django/exam/views.py
2024-10-22 00:34:38 +08:00

302 lines
10 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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