diff --git a/atlas/forms.py b/atlas/forms.py index 9f81b346..63aa1926 100755 --- a/atlas/forms.py +++ b/atlas/forms.py @@ -7,9 +7,11 @@ from django.forms import ( ModelChoiceField, ChoiceField, CharField, + ValidationError, modelformset_factory, ) from django.forms import inlineformset_factory +from django.shortcuts import get_object_or_404 from atlas.models import ( Case, @@ -52,6 +54,7 @@ class ConditionForm(ModelForm): ), } + class CaseCollectionForm(ModelForm): class Meta: model = CaseCollection @@ -73,6 +76,7 @@ class CaseCollectionForm(ModelForm): super(CaseCollectionForm, self).__init__(*args, **kwargs) + class FindingForm(ModelForm): class Meta: model = Finding @@ -204,7 +208,7 @@ class SeriesForm(ModelForm): instance.save() self.save_m2m() - #instance.anonymise_images() + # instance.anonymise_images() return instance @@ -337,8 +341,6 @@ CaseDifferentialFormSet = inlineformset_factory( ) - - class CaseSeriesForm(ModelForm): def __init__(self, *args, user, **kwargs): super(CaseSeriesForm, self).__init__(*args, **kwargs) @@ -354,10 +356,11 @@ class CaseSeriesForm(ModelForm): # widget=Select(verbose_name="Series", is_stacked=False), ) + class CaseCollectionCaseForm(ModelForm): def __init__(self, *args, user, **kwargs): super(CaseCollectionCaseForm, self).__init__(*args, **kwargs) - + if not user.groups.filter(name="atlas_editor").exists(): queryset = Case.objects.filter(author__id=user.id) else: @@ -369,6 +372,7 @@ class CaseCollectionCaseForm(ModelForm): # widget=Select(verbose_name="Series", is_stacked=False), ) + SeriesFormSet = inlineformset_factory( Case, Series.case.through, @@ -399,6 +403,7 @@ SeriesImageFormSet = inlineformset_factory( max_num=2000, ) + class CidReportAnswerForm(ModelForm): class Meta: model = CidReportAnswer @@ -413,13 +418,14 @@ class CidReportAnswerForm(ModelForm): "answer": Textarea(attrs={"cols": 100, "rows": 5}), } - #help_texts = { + # help_texts = { # "answer": "Write your answer in here." - #} + # } def __init__(self, *args, **kwargs): super(CidReportAnswerForm, self).__init__(*args, **kwargs) - self.fields['answer'].required = False + self.fields["answer"].required = False + class CidReportAnswerMarkForm(ModelForm): class Meta: @@ -437,4 +443,88 @@ class CidReportAnswerMarkForm(ModelForm): def __init__(self, *args, **kwargs): super(CidReportAnswerMarkForm, self).__init__(*args, **kwargs) - self.fields['score'].required = False + self.fields["score"].required = False + + +#class AddCollectionToCaseForm(Form): +# +# def __init__(self, *args, user, **kwargs): +# super(AddCollectionToCaseForm, self).__init__(*args, **kwargs) +# print("INIT", args, kwargs) +# +# if not user.groups.filter(name="atlas_editor").exists(): +# queryset = CaseCollection.objects.filter(author__id=user.id) +# else: +# queryset = CaseCollection.objects.all() +# +# self.valid_collections = queryset +# self.case = get_object_or_404(Case, pk=pk) +# +# self.fields["casecollection"] = ModelMultipleChoiceField( +# required=False, +# queryset=queryset, +# # widget=Select(verbose_name="Series", is_stacked=False), +# ) +# +# def save(self, *args, **kwargs): +# print("SAVE", args, kwargs) +# instance = super(AddCollectionToCaseForm, self).save(*args, **kwargs) +# +# # Here we save the modified project selection back into the database +# instance.casecollection_set.set(self.cleaned_data['casecollection']) +# +# print(f"{instance=}") +# +# return instance +# +# def clean_casecollection(self): +# collection_set = self.cleaned_data["casecollection"] +# +# print(f"{collection_set=}") +# +# for col in collection_set: +# if col not in self.valid_collections: +# raise ValidationError("Invalid collection") +# +# return collection_set + +class AddCollectionToCaseForm(Form): + + def __init__(self, *args, user, **kwargs): + super(AddCollectionToCaseForm, self).__init__(*args, **kwargs) + print("INIT", args, kwargs) + + if not user.groups.filter(name="atlas_editor").exists(): + queryset = CaseCollection.objects.filter(author__id=user.id) + else: + queryset = CaseCollection.objects.all() + + self.valid_collections = queryset + + self.fields["casecollection"] = ModelMultipleChoiceField( + required=False, + queryset=queryset, + # widget=Select(verbose_name="Series", is_stacked=False), + ) + + def save(self, *args, **kwargs): + print("SAVE", args, kwargs) + instance = super(AddCollectionToCaseForm, self).save(*args, **kwargs) + + # Here we save the modified project selection back into the database + instance.casecollection_set.set(self.cleaned_data['casecollection']) + + print(f"{instance=}") + + return instance + + def clean_casecollection(self): + collection_set = self.cleaned_data["casecollection"] + + print(f"{collection_set=}") + + for col in collection_set: + if col not in self.valid_collections: + raise ValidationError("Invalid collection") + + return collection_set diff --git a/atlas/migrations/0046_alter_casedetail_sort_order.py b/atlas/migrations/0046_alter_casedetail_sort_order.py new file mode 100644 index 00000000..ed7679ba --- /dev/null +++ b/atlas/migrations/0046_alter_casedetail_sort_order.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.13 on 2022-07-05 20:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('atlas', '0045_rename_valid_users_casecollection_valid_cid_users'), + ] + + operations = [ + migrations.AlterField( + model_name='casedetail', + name='sort_order', + field=models.IntegerField(default=1000), + ), + ] diff --git a/atlas/models.py b/atlas/models.py index c7bf595a..c4796f70 100644 --- a/atlas/models.py +++ b/atlas/models.py @@ -739,7 +739,7 @@ class CaseDetail(models.Model): case = models.ForeignKey(Case, on_delete=models.CASCADE) collection = models.ForeignKey(CaseCollection, on_delete=models.CASCADE) - sort_order = models.IntegerField() + sort_order = models.IntegerField(default=1000) class Meta: ordering = ("sort_order",) diff --git a/atlas/templates/atlas/case_display_block.html b/atlas/templates/atlas/case_display_block.html index fe8c02be..5e86d483 100755 --- a/atlas/templates/atlas/case_display_block.html +++ b/atlas/templates/atlas/case_display_block.html @@ -111,6 +111,11 @@ {% endfor %} Collections: + +
- \ No newline at end of file + \ No newline at end of file diff --git a/generic/templates/generic/exam_scores_base.html b/generic/templates/generic/exam_scores_base.html index 57d07dcb..3113d4d9 100644 --- a/generic/templates/generic/exam_scores_base.html +++ b/generic/templates/generic/exam_scores_base.html @@ -90,8 +90,19 @@
Email results User results emailed: {{exam.exam_results_emailed|default:"Never"}}
- - + + @@ -100,50 +111,5 @@
- - {% endblock %} diff --git a/generic/views.py b/generic/views.py index 7cd98ff2..f9d38cee 100644 --- a/generic/views.py +++ b/generic/views.py @@ -593,7 +593,8 @@ class ExamViews(View, LoginRequiredMixin): for u in users: user = User.objects.get(pk=u) user_exam = exam.get_or_create_cid_user_exam(user_user=user) - status[user] = json.loads(user_exam.results_emailed_status) + if user_exam.results_emailed_status: + status[user] = json.loads(user_exam.results_emailed_status) return render( request, @@ -620,7 +621,11 @@ class ExamViews(View, LoginRequiredMixin): if not self.check_user_access(request.user, exam_id): raise PermissionDenied - additional_email = request.GET.get("additional_email", "") + additional_email = False + if request.htmx.prompt is not None: + additional_email = request.htmx.prompt + + print(f"{additional_email=}") # check addition email is valid if additional_email: @@ -646,19 +651,29 @@ class ExamViews(View, LoginRequiredMixin): continue if additional_email: - email_results[user.pk] = exam.email_user_results( + email_results[user] = exam.email_user_results( user, additional_emails=[additional_email] ) else: - email_results[user.pk] = exam.email_user_results(user) - email_results[user.pk].append(f"{time}") - user_exam.results_emailed_status = json.dumps(email_results[user.pk]) + email_results[user] = exam.email_user_results(user) + email_results[user].append(f"{time}") + user_exam.results_emailed_status = json.dumps(email_results[user]) user_exam.save() exam.exam_results_emailed = time exam.save() + return render( + request, + "generic/exam_report_email_status.html", + { + "exam": exam, + "status": email_results, + "app_name": self.app_name, + }, + ) + return JsonResponse(email_results) @method_decorator(login_required) @@ -1343,7 +1358,7 @@ class ExamViews(View, LoginRequiredMixin): if not existing_answers: if uid: ans = self.CidUserAnswer( - answer=posted_answer, uid=User.objects.get(id=uid) + answer=posted_answer, user=User.objects.get(id=uid) ) else: ans = self.CidUserAnswer(answer=posted_answer, cid=cid) diff --git a/templates/base.html b/templates/base.html index f0e78a93..5668494d 100644 --- a/templates/base.html +++ b/templates/base.html @@ -25,7 +25,8 @@ - + {% comment %} {% endcomment %} + {% django_htmx_script %} diff --git a/templates/generic_form.html b/templates/generic_form.html new file mode 100644 index 00000000..4a0f7318 --- /dev/null +++ b/templates/generic_form.html @@ -0,0 +1,6 @@ +
+ {% csrf_token %} + {{ form }} + + +
\ No newline at end of file