create base useranswer class

This commit is contained in:
Ross
2023-05-15 11:12:52 +01:00
parent 525373f393
commit 7aa78c2807
33 changed files with 198 additions and 131 deletions
+3 -3
View File
@@ -2,7 +2,7 @@ import django_filters
from .models import AnatomyQuestion, CidUserAnswer, Exam
#from generic.filters import UserAnswerFilter
#from generic.filters import CidUserAnswerFilter
from django.contrib.auth.models import User
@@ -46,7 +46,7 @@ class AnatomyQuestionFilter(django_filters.FilterSet):
super(AnatomyQuestionFilter, self).__init__(data=data, queryset=queryset, prefix=prefix, request=request)
pass
class AnatomyUserAnswerFilter(django_filters.FilterSet):
class AnatomyCidUserAnswerFilter(django_filters.FilterSet):
class Meta:
model= CidUserAnswer
fields = (
@@ -63,5 +63,5 @@ class AnatomyUserAnswerFilter(django_filters.FilterSet):
def __init__(self, data=None, queryset=None, prefix=None, strict=None, user=None, request=None):
if not request.user.groups.filter(name="anatomy_checker").exists():
queryset = queryset.filter(open_access=True) | queryset.filter(author__id=request.user.id)
super(AnatomyUserAnswerFilter, self).__init__(data=data, queryset=queryset, prefix=prefix, request=request)
super(AnatomyCidUserAnswerFilter, self).__init__(data=data, queryset=queryset, prefix=prefix, request=request)
pass
@@ -0,0 +1,17 @@
# Generated by Django 4.1.4 on 2023-05-15 10:11
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('anatomy', '0067_alter_anatomyquestion_image'),
]
operations = [
migrations.AlterModelOptions(
name='ciduseranswer',
options={'ordering': ['cid']},
),
]
+2 -11
View File
@@ -16,7 +16,7 @@ from sortedm2m.fields import SortedManyToManyField
import string
from generic.models import CidUser, CidUserGroup, ExamUserStatus, Examination, ExamBase, QuestionNote, UserUserGroup
from generic.models import CidUser, CidUserGroup, ExamUserStatus, Examination, ExamBase, QuestionNote, CidUserAnswerBase, UserUserGroup
from collections import defaultdict
from helpers.images import image_as_base64
@@ -467,7 +467,7 @@ class Exam(ExamBase):
@reversion.register
class CidUserAnswer(models.Model):
class CidUserAnswer(CidUserAnswerBase):
"""User answers by candidate"""
question = models.ForeignKey(
@@ -477,12 +477,6 @@ class CidUserAnswer(models.Model):
answer_compare = models.TextField(max_length=500, blank=True)
cid = models.BigIntegerField(
blank=True,
null=True,
help_text="Candidate ID (limitied by BigIntegerField size)",
)
user = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True, related_name="user_anatomy_user_answers"
)
@@ -492,9 +486,6 @@ class CidUserAnswer(models.Model):
Exam, related_name="cid_user_answers", on_delete=models.CASCADE, null=True
)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
score = models.CharField(
max_length=1,
choices=Answer.MarkOptions.choices,
+2 -2
View File
@@ -9,7 +9,7 @@ from easy_thumbnails.files import get_thumbnailer
from easy_thumbnails.exceptions import InvalidImageFormatError
#from generic.tables import UserAnswerTable
#from generic.tables import CidUserAnswerTable
class ImageColumn(tables.Column):
@@ -64,7 +64,7 @@ class AnatomyQuestionTable(tables.Table):
*args,
**kwargs,
)
class AnatomyUserAnswerTable(tables.Table):
class AnatomyCidUserAnswerTable(tables.Table):
select = tables.CheckBoxColumn(accessor=("pk"))
delete = tables.LinkColumn(
"anatomy:user_answer_delete", text="Delete", args=[A("pk")], orderable=False
+3 -3
View File
@@ -73,15 +73,15 @@ urlpatterns = [
),
path(
"user_answers/",
views.UserAnswerTableView.as_view(),
views.CidUserAnswerTableView.as_view(),
name="user_answer_table_view",
),
path(
"user_answers/<int:pk>", views.UserAnswerView.as_view(), name="user_answer_view"
"user_answers/<int:pk>", views.CidUserAnswerView.as_view(), name="user_answer_view"
),
path(
"user_answers/<int:pk>/delete",
views.UserAnswerDelete.as_view(),
views.CidUserAnswerDelete.as_view(),
name="user_answer_delete",
),
path(
+12 -12
View File
@@ -55,8 +55,8 @@ from reversion.views import RevisionMixin
from .decorators import user_is_author_or_anatomy_checker
from .tables import AnatomyQuestionTable, AnatomyUserAnswerTable
from .filters import AnatomyQuestionFilter, AnatomyUserAnswerFilter
from .tables import AnatomyQuestionTable, AnatomyCidUserAnswerTable
from .filters import AnatomyQuestionFilter, AnatomyCidUserAnswerFilter
from django_tables2 import SingleTableView, SingleTableMixin
from django_filters.views import FilterView
@@ -161,12 +161,12 @@ def answer_question(request, pk):
# }
#
# # Get data for flagged
# # answered_questions = UserAnswer.objects.filter(user=request.user).values_list("question__pk", flat=True)
# user_answer_data = UserAnswer.objects.filter(user=request.user).values_list(
# # answered_questions = CidUserAnswer.objects.filter(user=request.user).values_list("question__pk", flat=True)
# user_answer_data = CidUserAnswer.objects.filter(user=request.user).values_list(
# "question__pk", "answer", "flagged"
# )
# # flagged_questions = UserAnswer.objects.filter(user=request.user, flagged=True).values_list("question__pk", flat=True)
# # flagged_questions I= UserAnswer.filter(user=request.user, ).values_list("question__pk", flat=True)
# # flagged_questions = CidUserAnswer.objects.filter(user=request.user, flagged=True).values_list("question__pk", flat=True)
# # flagged_questions I= CidUserAnswer.filter(user=request.user, ).values_list("question__pk", flat=True)
#
# answered_questions = set()
# flagged_questions = set()
@@ -215,7 +215,7 @@ def answer_question(request, pk):
# def flag_question(request):
# pk = request.GET.get("pk", None)
# ans = UserAnswer.objects.filter(user=request.user, question__pk=pk).first()
# ans = CidUserAnswer.objects.filter(user=request.user, question__pk=pk).first()
# ans.flagged = not ans.flagged
# ans.save()
# data = {"flagged": ans.flagged}
@@ -737,19 +737,19 @@ GenericExamViews = ExamViews(
)
class UserAnswerView(SuperuserRequiredMixin, DetailView):
class CidUserAnswerView(SuperuserRequiredMixin, DetailView):
model = CidUserAnswer
class UserAnswerTableView(SuperuserRequiredMixin, SingleTableMixin, FilterView):
class CidUserAnswerTableView(SuperuserRequiredMixin, SingleTableMixin, FilterView):
model = CidUserAnswer
table_class = AnatomyUserAnswerTable
table_class = AnatomyCidUserAnswerTable
template_name = "anatomy/user_answer_question_view.html"
filterset_class = AnatomyUserAnswerFilter
filterset_class = AnatomyCidUserAnswerFilter
class UserAnswerDelete(SuperuserRequiredMixin, DeleteView):
class CidUserAnswerDelete(SuperuserRequiredMixin, DeleteView):
model = CidUserAnswer
template_name = "user_answer_delete.html"
success_url = reverse_lazy("anatomy:user_answer_table_view")
+28
View File
@@ -394,6 +394,34 @@ class ExamUserStatus(models.Model):
return f"{self.datetime}: {user} - {self.status} ({self.extra})"
class CidUserAnswerBase(models.Model):
cid = models.BigIntegerField(
blank=True,
null=True,
help_text="Candidate ID (limitied by BigIntegerField size)",
)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
ordering = ["cid"]
def get_candidate_name(self) -> str:
if self.cid is not None:
return str(self.cid)
else:
return self.user.username
def get_candidate_masked(self) -> str:
if self.cid is not None:
return str(self.cid)
else:
return str(self.user.id)
class NoteType(models.Model):
note_type = models.CharField(max_length=200)
+1 -1
View File
@@ -1527,7 +1527,7 @@ class ExamViews(View, LoginRequiredMixin):
n = n + 1
# print(UserAnswer.objects.filter(exam__id=q["eid"]))
# print(CidUserAnswer.objects.filter(exam__id=q["eid"]))
# print(request.urlencode())
exam_type, exam_id = request.POST.get("eid").split("/")
+2 -2
View File
@@ -53,7 +53,7 @@ class LongSeriesFilter(django_filters.FilterSet):
super(LongSeriesFilter, self).__init__(data=data, queryset=queryset, prefix=prefix, request=request)
pass
class UserAnswerFilter(django_filters.FilterSet):
class CidUserAnswerFilter(django_filters.FilterSet):
class Meta:
model = CidUserAnswer
fields = (
@@ -69,5 +69,5 @@ class UserAnswerFilter(django_filters.FilterSet):
def __init__(self, data=None, queryset=None, prefix=None, strict=None, user=None, request=None):
if not request.user.groups.filter(name="long_checker").exists():
queryset = queryset.filter(open_access=True) | queryset.filter(author__id=request.user.id)
super(UserAnswerFilter, self).__init__(data=data, queryset=queryset, prefix=prefix, request=request)
super(CidUserAnswerFilter, self).__init__(data=data, queryset=queryset, prefix=prefix, request=request)
pass
+2 -16
View File
@@ -38,6 +38,7 @@ from generic.models import (
Plane,
Contrast,
QuestionNote,
CidUserAnswerBase,
UserUserGroup,
)
@@ -752,7 +753,7 @@ class Exam(ExamBase):
@reversion.register
class CidUserAnswer(models.Model):
class CidUserAnswer(CidUserAnswerBase):
"""User answers by candidate"""
question = models.ForeignKey(
@@ -812,11 +813,7 @@ class CidUserAnswer(models.Model):
# "AnswerMarks", related_name="user_answer", on_delete=models.SET_NULL, null=True, blank=True
# )
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ["cid"]
def __str__(self):
try:
@@ -885,17 +882,6 @@ class CidUserAnswer(models.Model):
def get_absolute_url(self):
return reverse("longs:user_answer_view", kwargs={"pk": self.pk})
def get_candidate_name(self) -> str:
if self.cid is not None:
return str(self.cid)
else:
return self.user.username
def get_candidate_masked(self) -> str:
if self.cid is not None:
return str(self.cid)
else:
return str(self.user.id)
@reversion.register
+1 -1
View File
@@ -130,7 +130,7 @@ class LongSeriesTable(tables.Table):
print(self)
return format_html("""<a href="#" onclick="return window.create_popup_window('/longs/series/{}', 'Series')" >Popup</a>""", record.pk)
class UserAnswerTable(tables.Table):
class CidUserAnswerTable(tables.Table):
select = tables.CheckBoxColumn(accessor=("pk"))
delete = tables.LinkColumn(
"longs:user_answer_delete", text="Delete", args=[A("pk")], orderable=False
+3 -3
View File
@@ -136,15 +136,15 @@ urlpatterns = [
),
path(
"user_answers/",
views.UserAnswerTableView.as_view(),
views.CidUserAnswerTableView.as_view(),
name="user_answer_table_view",
),
path(
"user_answers/<int:pk>", views.UserAnswerView.as_view(), name="user_answer_view"
"user_answers/<int:pk>", views.CidUserAnswerView.as_view(), name="user_answer_view"
),
path(
"user_answers/<int:pk>/delete",
views.UserAnswerDelete.as_view(),
views.CidUserAnswerDelete.as_view(),
name="user_answer_delete",
),
path(
+7 -7
View File
@@ -43,8 +43,8 @@ from .models import (
Exam,
CidUserAnswer,
)
from .tables import LongTable, LongSeriesTable, UserAnswerTable
from .filters import LongFilter, LongSeriesFilter, UserAnswerFilter
from .tables import LongTable, LongSeriesTable, CidUserAnswerTable
from .filters import LongFilter, LongSeriesFilter, CidUserAnswerFilter
from django_tables2 import SingleTableView, SingleTableMixin
from django_filters.views import FilterView
@@ -1194,19 +1194,19 @@ def question_json_recreate(request, pk):
return redirect("longs:question_detail", pk=pk)
class UserAnswerView(LoginRequiredMixin, DetailView):
class CidUserAnswerView(LoginRequiredMixin, DetailView):
model = CidUserAnswer
class UserAnswerTableView(LoginRequiredMixin, SingleTableMixin, FilterView):
class CidUserAnswerTableView(LoginRequiredMixin, SingleTableMixin, FilterView):
model = CidUserAnswer
table_class = UserAnswerTable
table_class = CidUserAnswerTable
template_name = "longs/user_answer_question_view.html"
filterset_class = UserAnswerFilter
filterset_class = CidUserAnswerFilter
class UserAnswerDelete(SuperuserRequiredMixin, DeleteView):
class CidUserAnswerDelete(SuperuserRequiredMixin, DeleteView):
model = CidUserAnswer
template_name = "user_answer_delete.html"
success_url = reverse_lazy("longs:user_answer_table_view")
+3 -3
View File
@@ -2,7 +2,7 @@ import django_filters
from .models import Category, Question, CidUserAnswer, Exam
#from generic.filters import UserAnswerFilter
#from generic.filters import CidUserAnswerFilter
from django.contrib.auth.models import User
@@ -43,7 +43,7 @@ class QuestionFilter(django_filters.FilterSet):
super(QuestionFilter, self).__init__(data=data, queryset=queryset, prefix=prefix, request=request)
pass
class UserAnswerFilter(django_filters.FilterSet):
class CidUserAnswerFilter(django_filters.FilterSet):
class Meta:
model= CidUserAnswer
fields = (
@@ -59,5 +59,5 @@ class UserAnswerFilter(django_filters.FilterSet):
def __init__(self, data=None, queryset=None, prefix=None, strict=None, user=None, request=None):
if not request.user.groups.filter(name="physics_checker").exists():
queryset = queryset.filter(author__id=request.user.id)
super(UserAnswerFilter, self).__init__(data=data, queryset=queryset, prefix=prefix, request=request)
super(CidUserAnswerFilter, self).__init__(data=data, queryset=queryset, prefix=prefix, request=request)
pass
@@ -0,0 +1,22 @@
# Generated by Django 4.1.4 on 2023-05-15 10:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('physics', '0026_remove_exam_stats_graph'),
]
operations = [
migrations.AlterModelOptions(
name='ciduseranswer',
options={'ordering': ['cid']},
),
migrations.AlterField(
model_name='ciduseranswer',
name='cid',
field=models.BigIntegerField(blank=True, help_text='Candidate ID (limitied by BigIntegerField size)', null=True),
),
]
+2 -6
View File
@@ -12,7 +12,7 @@ from django.utils.translation import gettext_lazy as _
from sortedm2m.fields import SortedManyToManyField
from generic.models import CidUser, CidUserGroup, ExamBase, ExamUserStatus, QuestionNote, UserUserGroup
from generic.models import CidUser, CidUserGroup, ExamBase, ExamUserStatus, QuestionNote, CidUserAnswerBase, UserUserGroup
import reversion
@@ -182,7 +182,7 @@ class Exam(ExamBase):
@reversion.register
class CidUserAnswer(models.Model):
class CidUserAnswer(CidUserAnswerBase):
"""User answers by candidate"""
question = models.ForeignKey(
@@ -194,8 +194,6 @@ class CidUserAnswer(models.Model):
d = models.BooleanField(blank=False)
e = models.BooleanField(blank=False)
cid = models.IntegerField(blank=True, null=True)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
@@ -209,8 +207,6 @@ class CidUserAnswer(models.Model):
Exam, related_name="cid_user_answers", on_delete=models.CASCADE, null=True
)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return "{}/{}/{}".format(self.cid, self.exam, self.question.pk)
+2 -2
View File
@@ -10,7 +10,7 @@ from django.utils.html import format_html
# from easy_thumbnails.exceptions import InvalidImageFormatError
# from generic.tables import UserAnswerTable
# from generic.tables import CidUserAnswerTable
# class ImageColumn(tables.Column):
@@ -75,7 +75,7 @@ class QuestionTable(tables.Table):
return mark_safe(value)
class UserAnswerTable(tables.Table):
class CidUserAnswerTable(tables.Table):
select = tables.CheckBoxColumn(accessor=("pk"))
# delete = tables.LinkColumn(
# "physics:user_answer_delete", text="Delete", args=[A("pk")], orderable=False
+3 -3
View File
@@ -51,17 +51,17 @@ urlpatterns.extend(
# path("exam/json/<int:pk>/recreate", views.exam_json_recreate, name="exam_json_recreate"),
path(
"user_answers/",
views.UserAnswerTableView.as_view(),
views.CidUserAnswerTableView.as_view(),
name="user_answer_table_view",
),
path(
"user_answers/<int:pk>",
views.UserAnswerView.as_view(),
views.CidUserAnswerView.as_view(),
name="user_answer_view",
),
path(
"user_answers/<int:pk>/delete",
views.UserAnswerDelete.as_view(),
views.CidUserAnswerDelete.as_view(),
name="user_answer_delete",
),
path(
+7 -7
View File
@@ -2,9 +2,9 @@ from django.contrib.contenttypes.models import ContentType
from django.utils import timezone
from generic.models import CidUser
from physics.decorators import user_is_author_or_physics_checker
from physics.filters import QuestionFilter, UserAnswerFilter
from physics.filters import QuestionFilter, CidUserAnswerFilter
from generic.mixins import SuperuserRequiredMixin
from physics.tables import QuestionTable, UserAnswerTable
from physics.tables import QuestionTable, CidUserAnswerTable
from django.shortcuts import render, get_object_or_404, redirect
from django.views.decorators.csrf import csrf_exempt
from django import forms
@@ -457,21 +457,21 @@ class QuestionView(
class UserAnswerView(AuthorOrCheckerRequiredMixin, LoginRequiredMixin, DetailView):
class CidUserAnswerView(AuthorOrCheckerRequiredMixin, LoginRequiredMixin, DetailView):
model = CidUserAnswer
class UserAnswerTableView(
class CidUserAnswerTableView(
AuthorOrCheckerRequiredMixin, LoginRequiredMixin, SingleTableMixin, FilterView
):
model = CidUserAnswer
table_class = UserAnswerTable
table_class = CidUserAnswerTable
template_name = "physics/user_answer_question_view.html"
filterset_class = UserAnswerFilter
filterset_class = CidUserAnswerFilter
class UserAnswerDelete(SuperuserRequiredMixin, DeleteView):
class CidUserAnswerDelete(SuperuserRequiredMixin, DeleteView):
model = CidUserAnswer
template_name = "user_answer_delete.html"
success_url = reverse_lazy("physics:user_answer_table_view")
+1 -1
View File
@@ -47,7 +47,7 @@ router_drf = routers.DefaultRouter()
#)
#router_drf.register(
# r"rapids/user_answer",
# rapid_views.UserAnswerViewSet,
# rapid_views.CidUserAnswerViewSet,
# basename="rapid-question-answers",
#)
#router_drf.register(r"rapids", rapid_views.RapidViewSet, basename="rapid")
+2 -2
View File
@@ -68,7 +68,7 @@ class RapidFilter(django_filters.FilterSet):
pass
class RapidUserAnswerFilter(django_filters.FilterSet):
class RapidCidUserAnswerFilter(django_filters.FilterSet):
class Meta:
model = CidUserAnswer
fields = (
@@ -95,7 +95,7 @@ class RapidUserAnswerFilter(django_filters.FilterSet):
queryset = queryset.filter(open_access=True) | queryset.filter(
author__id=request.user.id
)
super(RapidUserAnswerFilter, self).__init__(
super(RapidCidUserAnswerFilter, self).__init__(
data=data, queryset=queryset, prefix=prefix, request=request
)
pass
@@ -0,0 +1,17 @@
# Generated by Django 4.1.4 on 2023-05-15 10:11
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('rapids', '0061_remove_exam_stats_graph'),
]
operations = [
migrations.AlterModelOptions(
name='ciduseranswer',
options={'ordering': ['cid']},
),
]
+2 -9
View File
@@ -34,6 +34,7 @@ from generic.models import (
#Sign,
ExamBase,
QuestionNote,
CidUserAnswerBase,
UserUserGroup,
)
@@ -768,7 +769,7 @@ class Exam(ExamBase):
@reversion.register
class CidUserAnswer(models.Model):
class CidUserAnswer(CidUserAnswerBase):
"""User answers by candidate"""
question = models.ForeignKey(
@@ -781,11 +782,6 @@ class CidUserAnswer(models.Model):
answer_compare = models.TextField(max_length=500, blank=True)
cid = models.BigIntegerField(
blank=True,
null=True,
help_text="Candidate ID (limitied by BigIntegerField size)",
)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
@@ -800,9 +796,6 @@ class CidUserAnswer(models.Model):
Exam, related_name="cid_user_answers", on_delete=models.CASCADE, null=True
)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
score = models.CharField(
max_length=1,
choices=Answer.MarkOptions.choices,
+1 -1
View File
@@ -18,7 +18,7 @@ class QuestionAnswerSerializer(serializers.HyperlinkedModelSerializer):
fields = ('id', 'question', 'answer', "answer_compare", "status")
view_name = "rapid-exam"
class UserAnswerSerializer(serializers.HyperlinkedModelSerializer):
class CidUserAnswerSerializer(serializers.HyperlinkedModelSerializer):
exam = serializers.HyperlinkedRelatedField(view_name='rapid-exam-detail',
read_only=True
)
+1 -1
View File
@@ -66,7 +66,7 @@ class RapidTable(tables.Table):
**kwargs,
)
class RapidUserAnswerTable(tables.Table):
class RapidCidUserAnswerTable(tables.Table):
select = tables.CheckBoxColumn(accessor=("pk"))
delete = tables.LinkColumn(
"rapids:user_answer_delete", text="Delete", args=[A("pk")], orderable=False
+3 -3
View File
@@ -83,15 +83,15 @@ urlpatterns = [
),
path(
"user_answers/",
views.UserAnswerTableView.as_view(),
views.CidUserAnswerTableView.as_view(),
name="user_answer_table_view",
),
path(
"user_answers/<int:pk>", views.UserAnswerView.as_view(), name="user_answer_view"
"user_answers/<int:pk>", views.CidUserAnswerView.as_view(), name="user_answer_view"
),
path(
"user_answers/<int:pk>/delete",
views.UserAnswerDelete.as_view(),
views.CidUserAnswerDelete.as_view(),
name="user_answer_delete",
),
path(
+10 -10
View File
@@ -54,8 +54,8 @@ from generic.views import (
from reversion.views import RevisionMixin
from .tables import RapidTable, RapidUserAnswerTable
from .filters import RapidFilter, RapidUserAnswerFilter
from .tables import RapidTable, RapidCidUserAnswerTable
from .filters import RapidFilter, RapidCidUserAnswerFilter
from django_tables2 import SingleTableView, SingleTableMixin
from django_filters.views import FilterView
@@ -86,7 +86,7 @@ from .serializers import (
QuestionAnswerSerializer,
RapidLateralitySerializer,
RapidSerializer,
UserAnswerSerializer,
CidUserAnswerSerializer,
)
from generic.mixins import SuperuserRequiredMixin
@@ -717,19 +717,19 @@ class ExamAuthorUpdate(
class UserAnswerView(LoginRequiredMixin, DetailView):
class CidUserAnswerView(LoginRequiredMixin, DetailView):
model = CidUserAnswer
class UserAnswerTableView(LoginRequiredMixin, SingleTableMixin, FilterView):
class CidUserAnswerTableView(LoginRequiredMixin, SingleTableMixin, FilterView):
model = CidUserAnswer
table_class = RapidUserAnswerTable
table_class = RapidCidUserAnswerTable
template_name = "rapids/user_answer_question_view.html"
filterset_class = RapidUserAnswerFilter
filterset_class = RapidCidUserAnswerFilter
class UserAnswerDelete(SuperuserRequiredMixin, DeleteView):
class CidUserAnswerDelete(SuperuserRequiredMixin, DeleteView):
model = CidUserAnswer
template_name = "user_answer_delete.html"
success_url = reverse_lazy("rapids:user_answer_table_view")
@@ -768,9 +768,9 @@ class ExamViewSet(RevisionMixin, viewsets.ModelViewSet):
# permission_classes = [permissions.IsAuthenticated]
#
#
#class UserAnswerViewSet(viewsets.ModelViewSet):
#class CidUserAnswerViewSet(viewsets.ModelViewSet):
# queryset = CidUserAnswer.objects.all() # .order_by('name')
# serializer_class = UserAnswerSerializer
# serializer_class = CidUserAnswerSerializer
# permission_classes = [permissions.IsAuthenticated]
+3 -3
View File
@@ -2,7 +2,7 @@ import django_filters
from .models import Category, Question, CidUserAnswer, Exam
#from generic.filters import UserAnswerFilter
#from generic.filters import CidUserAnswerFilter
from django.contrib.auth.models import User
@@ -43,7 +43,7 @@ class QuestionFilter(django_filters.FilterSet):
super(QuestionFilter, self).__init__(data=data, queryset=queryset, prefix=prefix, request=request)
pass
class UserAnswerFilter(django_filters.FilterSet):
class CidUserAnswerFilter(django_filters.FilterSet):
class Meta:
model= CidUserAnswer
fields = (
@@ -59,5 +59,5 @@ class UserAnswerFilter(django_filters.FilterSet):
def __init__(self, data=None, queryset=None, prefix=None, strict=None, user=None, request=None):
if not request.user.groups.filter(name="sba_checker").exists():
queryset = queryset.filter(open_access=True) | queryset.filter(author__id=request.user.id)
super(UserAnswerFilter, self).__init__(data=data, queryset=queryset, prefix=prefix, request=request)
super(CidUserAnswerFilter, self).__init__(data=data, queryset=queryset, prefix=prefix, request=request)
pass
@@ -0,0 +1,22 @@
# Generated by Django 4.1.4 on 2023-05-15 10:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('sbas', '0016_remove_exam_stats_graph'),
]
operations = [
migrations.AlterModelOptions(
name='ciduseranswer',
options={'ordering': ['cid']},
),
migrations.AlterField(
model_name='ciduseranswer',
name='cid',
field=models.BigIntegerField(blank=True, help_text='Candidate ID (limitied by BigIntegerField size)', null=True),
),
]
+2 -7
View File
@@ -11,7 +11,7 @@ from django.utils.translation import gettext_lazy as _
from sortedm2m.fields import SortedManyToManyField
from generic.models import CidUser, CidUserGroup, ExamBase, ExamUserStatus, QuestionNote, UserUserGroup
from generic.models import CidUser, CidUserGroup, ExamBase, ExamUserStatus, QuestionNote, CidUserAnswerBase, UserUserGroup
import reversion
@@ -205,7 +205,7 @@ class Exam(ExamBase):
@reversion.register
class CidUserAnswer(models.Model):
class CidUserAnswer(CidUserAnswerBase):
"""User answers by candidate"""
question = models.ForeignKey(
@@ -217,8 +217,6 @@ class CidUserAnswer(models.Model):
help_text="The correct answer",
)
cid = models.IntegerField(blank=True, null=True)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
@@ -232,9 +230,6 @@ class CidUserAnswer(models.Model):
Exam, related_name="cid_user_answers", on_delete=models.CASCADE, null=True
)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return "{}/{}/{}".format(self.cid, self.exam, self.question.pk)
+2 -2
View File
@@ -10,7 +10,7 @@ from django.utils.html import format_html
#from easy_thumbnails.exceptions import InvalidImageFormatError
#from generic.tables import UserAnswerTable
#from generic.tables import CidUserAnswerTable
#class ImageColumn(tables.Column):
@@ -69,7 +69,7 @@ class QuestionTable(tables.Table):
return mark_safe(value)
class UserAnswerTable(tables.Table):
class CidUserAnswerTable(tables.Table):
select = tables.CheckBoxColumn(accessor=("pk"))
#delete = tables.LinkColumn(
# "sbas:user_answer_delete", text="Delete", args=[A("pk")], orderable=False
+3 -3
View File
@@ -50,15 +50,15 @@ urlpatterns = [
# path("exam/json/<int:pk>/recreate", views.exam_json_recreate, name="exam_json_recreate"),
path(
"user_answers/",
views.UserAnswerTableView.as_view(),
views.CidUserAnswerTableView.as_view(),
name="user_answer_table_view",
),
path(
"user_answers/<int:pk>", views.UserAnswerView.as_view(), name="user_answer_view"
"user_answers/<int:pk>", views.CidUserAnswerView.as_view(), name="user_answer_view"
),
path(
"user_answers/<int:pk>/delete",
views.UserAnswerDelete.as_view(),
views.CidUserAnswerDelete.as_view(),
name="user_answer_delete",
),
path(
+7 -7
View File
@@ -48,8 +48,8 @@ from rest_framework.pagination import PageNumberPagination
from django.core.exceptions import PermissionDenied
from .tables import QuestionTable, UserAnswerTable
from .filters import QuestionFilter, UserAnswerFilter
from .tables import QuestionTable, CidUserAnswerTable
from .filters import QuestionFilter, CidUserAnswerFilter
from .forms import (
QuestionForm,
@@ -404,19 +404,19 @@ class QuestionClone(QuestionCreateBase):
return initial_data
class UserAnswerView(LoginRequiredMixin, DetailView):
class CidUserAnswerView(LoginRequiredMixin, DetailView):
model = CidUserAnswer
class UserAnswerTableView(LoginRequiredMixin, SingleTableMixin, FilterView):
class CidUserAnswerTableView(LoginRequiredMixin, SingleTableMixin, FilterView):
model = CidUserAnswer
table_class = UserAnswerTable
table_class = CidUserAnswerTable
template_name = "sbas/user_answer_question_view.html"
filterset_class = UserAnswerFilter
filterset_class = CidUserAnswerFilter
class UserAnswerDelete(SuperuserRequiredMixin, DeleteView):
class CidUserAnswerDelete(SuperuserRequiredMixin, DeleteView):
model = CidUserAnswer
template_name = "user_answer_delete.html"
success_url = reverse_lazy("sbas:user_answer_table_view")