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