from django.shortcuts import render from django.http import HttpResponse from .models import * from django.shortcuts import render, redirect, get_object_or_404 import random from django.http import JsonResponse import pandas as pd import json from django.db.models import Window, F from django.db.models.functions import Rank from django.shortcuts import get_object_or_404 from django.views.decorators.csrf import csrf_exempt # 导入表单 from .forms import UploadFileForm @csrf_exempt def toregister_view(request): return JsonResponse({'message': '注册成功!'}) import json from django.views.decorators.csrf import csrf_exempt @csrf_exempt # 可选,视具体情况决定是否使用 def register_view(request): if request.method == 'POST': try: data = json.loads(request.body) # 从请求体中加载 JSON 数据 u = data.get("user", '') p = data.get("pwd", '') if u and p: stu = StudentInfo(stu_id=random.choice('0123456789'), stu_name=u, stu_pwd=p) stu.save() return JsonResponse({"message": "注册成功"}) else: return JsonResponse({"message": "请输入完整的账号和密码!"}, status=400) except json.JSONDecodeError: return JsonResponse({"message": "无效的 JSON 数据!"}, status=400) return JsonResponse({"message": "只支持 POST 请求!"}, status=405) # @csrf_exempt def upload_students(request): if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): # 读取上传的 Excel 文件 excel_file = request.FILES['file'] df = pd.read_excel(excel_file) # 使用 pandas 读取 Excel 文件 # 遍历 DataFrame,将每个学生保存到数据库 for _, row in df.iterrows(): student_id = row['student_id'] name = row['name'] Student.objects.get_or_create(student_id=student_id, name=name) # 如果学生已存在则不创建 return JsonResponse({"message": "学生信息上传成功!"}) else: form = UploadFileForm() return render(request, 'upload_students.html', {'form': form}) # 确保在GET请求时返回HttpResponse @csrf_exempt # 如果需要,可以移除此装饰器,确保 CSRF 保护 def roll_call(request): students = Student.objects.all() # 获取所有学生 # 当教师点击“开始点名”按钮时 if request.method == 'POST': try: data = json.loads(request.body) # 从请求中读取 JSON 数据 if data.get('start_roll_call') == 'true': # 设置权重:总分越高,被点名的概率越低 weights = [1 / (student.score + 1) for student in students] # 根据分数调整被点名概率 selected_student = random.choices(students, weights=weights, k=1)[0] # 随机选择一个学生 request.session['selected_student_id'] = selected_student.student_id # 存储被点名学生的ID到session中 return JsonResponse({"message": "点名成功", "student_id": selected_student.student_id, "student_name": selected_student.name}) except json.JSONDecodeError: return JsonResponse({"error": "无效的 JSON 数据"}, status=400) # 返回错误信息,如果不是 POST 请求或没有触发点名 return JsonResponse({"error": "只支持 POST 请求"}, status=405) @csrf_exempt def confirm_roll_call(request): if request.method == 'POST': try: # 从请求体中解析 JSON 数据 data = json.loads(request.body) student_id = data.get('student_id') # 确保 student_id 存在 if not student_id: return JsonResponse({"message": "未找到被点名学生ID"}, status=400) # 获取学生对象,若不存在则返回404 student = get_object_or_404(Student, student_id=student_id) protection_awarded = False # 初始化保护权标志 # 增加学生的被点名次数 student.called_count += 1 # 检查学生是否有“保护权” if student.called_count % 3 == 0: student.score += 2 protection_awarded = True # 设置保护权标志 print(f"Student {student.name} ({student.student_id})获得保护权,自动加2分") else: # 学生是否到课 attended = data.get('attended', 'false').lower() == 'true' # 转为布尔值 if attended: # 如果选择了到课 student.score += 1 # 到课加1分 student.attendance_count += 1 # 到课次数加1 # 处理是否准确重复问题 if data.get('question_repeat') == 'accurate': student.score += 0.5 # 重复问题准确,加0.5分 else: student.score -= 1 # 重复问题不准确,扣1分 # 处理回答问题的准确性(0-3分) answer_accuracy = float(data.get('answer_accuracy', 0)) student.score += answer_accuracy # 根据回答准确性加分 else: student.score -= 5 # 未到课扣5分 # 保存更新后的学生信息 student.save() return JsonResponse({ "message": "确认点名成功", "student_id": student.student_id, "student_name": student.name, "current_score": student.score, "protection_awarded": protection_awarded }) except json.JSONDecodeError: return JsonResponse({"message": "请求体解析错误"}, status=400) # GET 请求时渲染页面 return JsonResponse({"message": "不支持的请求方法"}, status=405) @csrf_exempt def leaderboard(request): students = Student.objects.all().order_by('-score') # 按分数降序排列 leaderboard_data = [{"student_id": student.student_id, "name": student.name, "score": student.score} for student in students] return JsonResponse({"leaderboard": leaderboard_data}) # 返回排行榜数据 # 111 @csrf_exempt # If you're testing without CSRF protection def toLogin_view(request): return JsonResponse({"message": "请提供用户名和密码进行登录"}) @csrf_exempt def Login_view(request): if request.method == 'POST': try: data = json.loads(request.body) u = data.get("user", '') p = data.get("pwd", '') if u and p: c = StudentInfo.objects.filter(stu_name=u, stu_pwd=p).count() if c >= 1: return JsonResponse({"message": "登录成功!"}) else: return JsonResponse({"message": "账号密码错误!"}, status=400) else: return JsonResponse({"message": "请输入正确的账号和密码!"}, status=400) except json.JSONDecodeError: return JsonResponse({"message": "无效的JSON数据!"}, status=400) return JsonResponse({"message": "仅支持POST请求"}, status=405)