Finish up questionnaire app

This commit is contained in:
Keannu Christian Bernasol 2024-11-24 10:34:41 +08:00
parent 8bd8df9042
commit b0a9b6b6f0
13 changed files with 558 additions and 25 deletions

View file

@ -0,0 +1,259 @@
# Generated by Django 5.1.3 on 2024-11-24 02:27
import django.db.models.deletion
import django.utils.timezone
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="Questionnaire",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"client_type",
models.CharField(
choices=[
("citizen", "Citizen"),
("business", "Business"),
("government", "Government (Employee or Another Agency)"),
],
max_length=32,
),
),
(
"date_submitted",
models.DateTimeField(
default=django.utils.timezone.now, editable=False
),
),
(
"sex",
models.CharField(
choices=[("male", "Male"), ("female", "Female")], max_length=16
),
),
("age", models.IntegerField()),
("region_of_residence", models.CharField(max_length=64)),
("service_availed", models.CharField(max_length=64)),
(
"i_am_a",
models.CharField(
choices=[
("faculty", "Faculty"),
("non-teaching staff", "Non-Teaching Staff"),
("student", "Student"),
("guardian", "Guardian/Parent of Student"),
("alumna", "Alumna"),
("other", "Other"),
],
max_length=32,
),
),
(
"i_am_a_other",
models.CharField(blank=True, max_length=64, null=True),
),
(
"q1_answer",
models.CharField(
choices=[
("1", "I know what a CC is and I saw this office's CC"),
(
"2",
"I know what a CC is but I did NOT see this office's CC",
),
(
"3",
"I learned of the CC only when I saw this office's CC",
),
(
"4",
"I do not know what a CC is and I did not see one in this office",
),
],
max_length=64,
),
),
(
"q2_answer",
models.CharField(
choices=[
("1", "Easy to see"),
("2", "Somewhat easy to see"),
("3", "Difficult to see"),
("4", "Not visible at all"),
("5", "N/A"),
],
max_length=64,
),
),
(
"q3_answer",
models.CharField(
choices=[
("1", "Helped very much"),
("2", "Somewhat helped"),
("3", "Did not help"),
("4", "N/A"),
],
max_length=64,
),
),
(
"sqd0_answer",
models.CharField(
choices=[
("1", "Strongly disagree"),
("2", "Disagree"),
("3", "Neither Agree nor Disagree"),
("4", "Agree"),
("5", "Strongly Agree"),
("6", "N/A"),
],
max_length=16,
),
),
(
"sqd1_answer",
models.CharField(
choices=[
("1", "Strongly disagree"),
("2", "Disagree"),
("3", "Neither Agree nor Disagree"),
("4", "Agree"),
("5", "Strongly Agree"),
("6", "N/A"),
],
max_length=16,
),
),
(
"sqd2_answer",
models.CharField(
choices=[
("1", "Strongly disagree"),
("2", "Disagree"),
("3", "Neither Agree nor Disagree"),
("4", "Agree"),
("5", "Strongly Agree"),
("6", "N/A"),
],
max_length=16,
),
),
(
"sqd3_answer",
models.CharField(
choices=[
("1", "Strongly disagree"),
("2", "Disagree"),
("3", "Neither Agree nor Disagree"),
("4", "Agree"),
("5", "Strongly Agree"),
("6", "N/A"),
],
max_length=16,
),
),
(
"sqd4_answer",
models.CharField(
choices=[
("1", "Strongly disagree"),
("2", "Disagree"),
("3", "Neither Agree nor Disagree"),
("4", "Agree"),
("5", "Strongly Agree"),
("6", "N/A"),
],
max_length=16,
),
),
(
"sqd5_answer",
models.CharField(
choices=[
("1", "Strongly disagree"),
("2", "Disagree"),
("3", "Neither Agree nor Disagree"),
("4", "Agree"),
("5", "Strongly Agree"),
("6", "N/A"),
],
max_length=16,
),
),
(
"sqd6_answer",
models.CharField(
choices=[
("1", "Strongly disagree"),
("2", "Disagree"),
("3", "Neither Agree nor Disagree"),
("4", "Agree"),
("5", "Strongly Agree"),
("6", "N/A"),
],
max_length=16,
),
),
(
"sqd7_answer",
models.CharField(
choices=[
("1", "Strongly disagree"),
("2", "Disagree"),
("3", "Neither Agree nor Disagree"),
("4", "Agree"),
("5", "Strongly Agree"),
("6", "N/A"),
],
max_length=16,
),
),
(
"sqd8_answer",
models.CharField(
choices=[
("1", "Strongly disagree"),
("2", "Disagree"),
("3", "Neither Agree nor Disagree"),
("4", "Agree"),
("5", "Strongly Agree"),
("6", "N/A"),
],
max_length=16,
),
),
(
"extra_suggestions",
models.TextField(blank=True, max_length=512, null=True),
),
(
"client",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
),
]

View file

@ -1,3 +1,113 @@
from django.db import models
from django.utils.timezone import now
# Create your models here.
class Questionnaire(models.Model):
# Personal Information
# Email address is derived from the user and is no longer optional
client = models.ForeignKey("accounts.CustomUser", on_delete=models.CASCADE)
CLIENT_TYPE_CHOICES = (
("citizen", "Citizen"),
("business", "Business"),
("government", "Government (Employee or Another Agency)"),
)
client_type = models.CharField(
max_length=32, choices=CLIENT_TYPE_CHOICES, null=False, blank=False
)
date_submitted = models.DateTimeField(default=now, editable=False)
SEX_CHOICES = (
("male", "Male"),
("female", "Female"),
)
sex = models.CharField(
max_length=16, choices=SEX_CHOICES, null=False, blank=False)
age = models.IntegerField(null=False, blank=False)
region_of_residence = models.CharField(
max_length=64, null=False, blank=False)
service_availed = models.CharField(max_length=64, null=False, blank=False)
I_AM_I_CHOICES = (
("faculty", "Faculty"),
("non-teaching staff", "Non-Teaching Staff"),
("student", "Student"),
("guardian", "Guardian/Parent of Student"),
("alumna", "Alumna"),
("other", "Other"),
)
i_am_a = models.CharField(
max_length=32, choices=I_AM_I_CHOICES, null=False, blank=False
)
# This is filled up if i_am_a=other
i_am_a_other = models.CharField(max_length=64, null=True, blank=True)
# CC Questions
Q1_CHOICES = (
("1", "I know what a CC is and I saw this office's CC"),
("2", "I know what a CC is but I did NOT see this office's CC"),
("3", "I learned of the CC only when I saw this office's CC"),
("4", "I do not know what a CC is and I did not see one in this office"),
)
q1_answer = models.CharField(
max_length=64, choices=Q1_CHOICES, null=False, blank=False
)
Q2_CHOICES = (
("1", "Easy to see"),
("2", "Somewhat easy to see"),
("3", "Difficult to see"),
("4", "Not visible at all"),
("5", "N/A"),
)
q2_answer = models.CharField(
max_length=64, choices=Q2_CHOICES, null=False, blank=False
)
Q3_CHOICES = (
("1", "Helped very much"),
("2", "Somewhat helped"),
("3", "Did not help"),
("4", "N/A"),
)
q3_answer = models.CharField(
max_length=64, choices=Q3_CHOICES, null=False, blank=False
)
# SQD Questions
SQD_CHOICES = (
("1", "Strongly disagree"),
("2", "Disagree"),
("3", "Neither Agree nor Disagree"),
("4", "Agree"),
("5", "Strongly Agree"),
("6", "N/A"),
)
sqd0_answer = models.CharField(
max_length=16, choices=SQD_CHOICES, null=False, blank=False
)
sqd1_answer = models.CharField(
max_length=16, choices=SQD_CHOICES, null=False, blank=False
)
sqd2_answer = models.CharField(
max_length=16, choices=SQD_CHOICES, null=False, blank=False
)
sqd3_answer = models.CharField(
max_length=16, choices=SQD_CHOICES, null=False, blank=False
)
sqd4_answer = models.CharField(
max_length=16, choices=SQD_CHOICES, null=False, blank=False
)
sqd5_answer = models.CharField(
max_length=16, choices=SQD_CHOICES, null=False, blank=False
)
sqd6_answer = models.CharField(
max_length=16, choices=SQD_CHOICES, null=False, blank=False
)
sqd7_answer = models.CharField(
max_length=16, choices=SQD_CHOICES, null=False, blank=False
)
sqd8_answer = models.CharField(
max_length=16, choices=SQD_CHOICES, null=False, blank=False
)
extra_suggestions = models.TextField(max_length=512, null=True, blank=True)

View file

@ -0,0 +1,90 @@
from rest_framework import serializers
from accounts.models import CustomUser
from .models import Questionnaire
class QuestionnaireSerializer(serializers.ModelSerializer):
client = serializers.SlugRelatedField(
many=False, slug_field="id", queryset=CustomUser.objects.all(), required=False
)
client_type = serializers.ChoiceField(
choices=Questionnaire.CLIENT_TYPE_CHOICES)
date_submitted = serializers.DateTimeField(
format="%m-%d-%Y %I:%M %p", read_only=True
)
sex = serializers.ChoiceField(choices=Questionnaire.SEX_CHOICES)
age = serializers.IntegerField(min_value=1)
region_of_residence = serializers.CharField(max_length=64)
service_availed = serializers.CharField(max_length=64)
i_am_a = serializers.ChoiceField(choices=Questionnaire.I_AM_I_CHOICES)
i_am_a_type_other = serializers.CharField(required=False)
q1_answer = serializers.ChoiceField(choices=Questionnaire.Q1_CHOICES)
q2_answer = serializers.ChoiceField(choices=Questionnaire.Q2_CHOICES)
q3_answer = serializers.ChoiceField(choices=Questionnaire.Q3_CHOICES)
sqd0_answer = serializers.ChoiceField(choices=Questionnaire.SQD_CHOICES)
sqd1_answer = serializers.ChoiceField(choices=Questionnaire.SQD_CHOICES)
sqd3_answer = serializers.ChoiceField(choices=Questionnaire.SQD_CHOICES)
sqd4_answer = serializers.ChoiceField(choices=Questionnaire.SQD_CHOICES)
sqd5_answer = serializers.ChoiceField(choices=Questionnaire.SQD_CHOICES)
sqd6_answer = serializers.ChoiceField(choices=Questionnaire.SQD_CHOICES)
sqd7_answer = serializers.ChoiceField(choices=Questionnaire.SQD_CHOICES)
sqd8_answer = serializers.ChoiceField(choices=Questionnaire.SQD_CHOICES)
extra_suggestions = serializers.CharField(max_length=512, required=False)
def to_representation(self, instance):
representation = super().to_representation(instance)
representation["client"] = instance.client.email
return super().to_representation(instance)
def create(self, validated_data):
user = self.context["request"].user
# Set questionnaire user to the one who sent the HTTP request to prevent spoofing
validated_data["client"] = user
if (
validated_data["client_type"] == "other"
and not validated_data["client_type_other"]
):
raise serializers.ValidationError(
{"error": "Missing description for client type: Other"}
)
# Create the instance without calling super().create()
instance = self.Meta.model(**validated_data)
# Explicitly set the client_type attribute
instance.client_type = validated_data.get("client_type")
# Save the instance
instance.save()
return instance
class Meta:
model = Questionnaire
fields = [
"id",
"client",
"client_type",
"date_submitted",
"sex",
"age",
"region_of_residence",
"service_availed",
"i_am_a",
"i_am_a_type_other",
"q1_answer",
"q2_answer",
"q3_answer",
"sqd0_answer",
"sqd1_answer",
"sqd2_answer",
"sqd3_answer",
"sqd4_answer",
"sqd5_answer",
"sqd6_answer",
"sqd7_answer",
"sqd8_answer",
"extra_suggestions",
]
read_only_fields = ["id", "date_submitted"]

View file

@ -0,0 +1,10 @@
from django.urls import include, path
from .views import (
QuestionnaireListAPIView,
QuestionnaireSubmitView,
)
urlpatterns = [
path("submit/", QuestionnaireSubmitView.as_view()),
path("list/", QuestionnaireListAPIView.as_view()),
]

View file

@ -1,3 +1,28 @@
from django.shortcuts import render
from rest_framework import generics
from .serializers import QuestionnaireSerializer
from rest_framework.permissions import IsAuthenticated
from .models import Questionnaire
from rest_framework.pagination import PageNumberPagination
from accounts.permissions import IsStaff
# Create your views here.
class QuestionnaireListAPIView(generics.ListAPIView):
"""
Used by staff to view questionnaires
"""
http_method_names = ["get"]
serializer_class = QuestionnaireSerializer
queryset = Questionnaire.objects.all()
pagination_class = PageNumberPagination
permission_classes = [IsAuthenticated, IsStaff]
class QuestionnaireSubmitView(generics.CreateAPIView):
"""
Used by clients to submit questionnaires
"""
http_method_names = ["post"]
serializer_class = QuestionnaireSerializer
permission_classes = [IsAuthenticated]