dormitory.views 源代码

from django.db import transaction
from rest_framework import viewsets

# TODO: Leaky dependency
from utils.marker import fix_me
from generic.models import User
from app.models import NaturalPerson
from app.view.base import ProfileTemplateView
from dormitory.models import Dormitory, DormitoryAssignment, Agreement
from dormitory.serializers import (
    DormitoryAssignmentSerializer, DormitorySerializer,
    AgreementSerializerFixme, AgreementSerializer)
from questionnaire.models import AnswerSheet, AnswerText, Survey
from semester.api import current_semester
from django.http import HttpResponse
from openpyxl import Workbook

[文档] class DormitoryViewSet(viewsets.ReadOnlyModelViewSet): queryset = Dormitory.objects.all() serializer_class = DormitorySerializer
[文档] class DormitoryAssignmentViewSet(viewsets.ReadOnlyModelViewSet): queryset = DormitoryAssignment.objects.all() serializer_class = DormitoryAssignmentSerializer
[文档] class DormitoryAgreementViewSetFixme(viewsets.ReadOnlyModelViewSet): serializer_class = AgreementSerializerFixme
[文档] def get_queryset(self): # Only active students need to sign the agreement require_agreement = User.objects.filter(active=True, utype=User.Type.STUDENT).contains(self.request.user) if require_agreement: return Agreement.objects.filter(user=self.request.user) # A hack to return something, so that the frontend won't redirect official_user = User.objects.get(username='zz00000') Agreement.objects.get_or_create(user=official_user) return Agreement.objects.filter(user=official_user)
[文档] class DormitoryAgreementViewSet(viewsets.ReadOnlyModelViewSet): queryset = Agreement.objects.all() serializer_class = AgreementSerializer
[文档] class DormitoryRoutineQAView(ProfileTemplateView): template_name = 'dormitory/routine_QA.html' page_name = '生活习惯调研' need_prepare = False
[文档] def get_survey(self): return Survey.objects.get(title=f'宿舍生活习惯调研-{current_semester().year}')
[文档] def get(self): survey = self.get_survey() if AnswerSheet.objects.filter(creator=self.request.user, survey=survey).exists(): return self.render(submitted=True) return self.render(survey_iter=[ (question, question.choices.order_by('order')) for question in survey.questions.order_by('order') ])
[文档] def post(self): survey = self.get_survey() assert not AnswerSheet.objects.filter(creator=self.request.user, survey=survey).exists() with transaction.atomic(): sheet = AnswerSheet.objects.create(creator=self.request.user, survey=survey) for question in survey.questions.order_by('order'): answer = self.request.POST.get(str(question.order)) if answer is None: assert not question.required, f"必填题{question.order}未作答" continue AnswerText.objects.create(question=question, answersheet=sheet, body=answer) return self.render(submitted=True)
[文档] class DormitoryAssignResultView(ProfileTemplateView): template_name = 'dormitory/assign_result.html' page_name = '宿舍分配结果' http_method_names = ['get'] need_prepare = False
[文档] def get(self): self.show_dorm_assign() return self.render()
[文档] def show_dorm_assign(self): user = self.request.user try: assignment = DormitoryAssignmentViewSet.queryset.get(user=user) dorm_assignment = DormitoryAssignmentViewSet.queryset.filter( dormitory=assignment.dormitory) roommates = [NaturalPerson.objects.get_by_user(assign.user) for assign in dorm_assignment.exclude(user=user)] self.extra_context.update( dorm_assigned=True, name=user.get_full_name(), dorm_id=assignment.dormitory.id, bed_id=assignment.bed_id, roommates=roommates, ) except DormitoryAssignment.DoesNotExist: self.extra_context.update(dorm_assigned=False)
[文档] class AgreementView(ProfileTemplateView): template_name = 'dormitory/agreement.html' page_name = '住宿协议' need_prepare = False
[文档] def get(self): return self.render()
[文档] @fix_me def post(self): Agreement.objects.get_or_create(user=self.request.user) from django.shortcuts import redirect return redirect("/welcome")
[文档] def download_xlsx(request) -> HttpResponse: wb = Workbook() ws = wb.active ws.title = "Result" survey = Survey.objects.get(title='宿舍生活习惯调研-2024') questions = survey.questions.order_by('order').all() # Add header row headers = [question.topic for question in questions] for col_num, column_title in enumerate(headers, 1): col_letter = ws.cell(row=1, column=col_num) col_letter.value = column_title # Iterate through the AnswerSheet objects for row_num, answer_sheet in enumerate(AnswerSheet.objects.filter(survey=survey), 2): answers = {answer.question.id: answer for answer in answer_sheet.answertext_set.all()} for col_num, question in enumerate(questions, 1): col_letter = ws.cell(row=row_num, column=col_num) answer = answers.get(question.id) if answer: if question.type == 'TEXT': col_letter.value = answer.body elif question.type == 'SINGLE': t = list(question.choices.filter(order=int(answer.body))) if len(t) != 1: raise ValueError(t) col_letter.value = question.choices.get(order=int(answer.body)).text elif question.type == 'MULTIPLE': choices_orders = answer.body.split(',') choices_texts = [question.choices.get(order=int(order)).text for order in choices_orders] col_letter.value = ', '.join(choices_texts) else: # If no answer, set as empty or a default value col_letter.value = None # or you can use "" or "N/A" # Save and return the workbook response = HttpResponse( content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') response['Content-Disposition'] = 'attachment; filename=questions.xlsx' wb.save(response) return response