.
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 5.0.2 on 2024-10-09 20:39
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('anatomy', '0021_alter_anatomyquestion_answer_help_and_more'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='exam',
|
||||
name='markers',
|
||||
field=models.ManyToManyField(blank=True, help_text='Authorised markers for the exam', related_name='anatomy_exam_markers', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 5.0.2 on 2024-10-09 20:39
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('atlas', '0061_alter_seriesfinding_current_image_id_index'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='casecollection',
|
||||
name='markers',
|
||||
field=models.ManyToManyField(blank=True, help_text='Authorised markers for the exam', related_name='casecollection_markers', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 5.0.2 on 2024-10-09 20:39
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('longs', '0028_alter_exam_double_mark'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='exam',
|
||||
name='markers',
|
||||
field=models.ManyToManyField(blank=True, help_text='Authorised markers for the exam', related_name='long_exam_markers', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
# Generated by Django 5.0.2 on 2024-10-09 20:39
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('oef', '0003_alter_formats_format'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Specialty',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=200)),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='formats',
|
||||
name='specialties',
|
||||
field=models.ManyToManyField(blank=True, to='oef.specialty'),
|
||||
),
|
||||
]
|
||||
+9
-1
@@ -37,6 +37,8 @@ class Formats(models.Model):
|
||||
|
||||
inherits = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True)
|
||||
|
||||
specialties = models.ManyToManyField('Specialty', blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@@ -58,4 +60,10 @@ class Formats(models.Model):
|
||||
formats.append(self.format)
|
||||
|
||||
formats.reverse()
|
||||
return "\n".join(formats)
|
||||
return "\n".join(formats)
|
||||
|
||||
class Specialty(models.Model):
|
||||
name = models.CharField(max_length=200)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
{% for entry in entries %}
|
||||
<li>{{entry.exam_code}}</li>
|
||||
{% endfor %}
|
||||
|
||||
@@ -1,113 +1,141 @@
|
||||
{% extends 'oef/base.html' %}
|
||||
{% block content %}
|
||||
<h2>Questions</h2>
|
||||
There are {{ questions|length }} question sets.
|
||||
<h2>Questions</h2>
|
||||
There are {{ questions|length }} question sets.
|
||||
|
||||
<div>Filter by:
|
||||
<textarea type="text" id="search-text" name="search" placeholder="Search text.." rows=5 cols=50 ></textarea>
|
||||
<div>Filter by:
|
||||
<textarea type="text" id="search-text" name="search" placeholder="Search text.." rows=5 cols=50 ></textarea>
|
||||
|
||||
<button
|
||||
|
||||
_="on click repeat for el in <li.question/>
|
||||
set p to the first <pre/> in el then
|
||||
if p.title does not contain value of #search-text then hide el">Filter</button>
|
||||
</div>
|
||||
<button
|
||||
|
||||
<div class="offcanvas offcanvas-end bg-dark" tabindex="-1" id="offcanvasExample" data-bs-scroll="true" data-bs-backdrop="false" aria-labelledby="offcanvasExampleLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="offcanvasExampleLabel">Comparisons</h5>
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<div>
|
||||
<ul id="sidebar-list">
|
||||
</ul>
|
||||
|
||||
_="on click repeat for el in <li.question/>
|
||||
set p to the first <pre/> in el then
|
||||
if p.title does not contain value of #search-text then hide el">Filter</button>
|
||||
</div>
|
||||
<button _="on click remove <li.sidebar-item/>">Clear</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
{% for question in questions %}
|
||||
<li class="question">
|
||||
<div class="offcanvas offcanvas-end bg-dark" tabindex="-1" id="offcanvasExample" data-bs-scroll="true" data-bs-backdrop="false" aria-labelledby="offcanvasExampleLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="offcanvasExampleLabel">Comparisons</h5>
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<div>
|
||||
<ul id="sidebar-list">
|
||||
</ul>
|
||||
<ul id="sidebar-codes">
|
||||
</li>
|
||||
|
||||
</div>
|
||||
<button _="on click remove <li.sidebar-item/>">Clear</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
{% for question, format in questions_and_formats %}
|
||||
<li class="question">
|
||||
<span class="format-name">
|
||||
{% if format %}
|
||||
<a href='{% url "oef:format_update" format.pk %}'>{{format.name}}</a>
|
||||
{% endif %}
|
||||
</span>
|
||||
<pre class="pre-question" title="{{ question }}">{{ question }}</pre>
|
||||
<form>
|
||||
<input type="hidden" name="question" value="{{ question }}">
|
||||
<button
|
||||
hx-post="{% url 'oef:entries_by_question' %}"
|
||||
hx-target="next .result"
|
||||
_="on click toggle @disabled until htmx:afterOnLoad then remove me"
|
||||
>View exams</button>
|
||||
<span class="result"></span>
|
||||
<button
|
||||
hx-post="{% url 'oef:questions_sym' %}"
|
||||
hx-target="next .results-sym"
|
||||
<form>
|
||||
<input type="hidden" name="question" value="{{ question }}">
|
||||
<button
|
||||
hx-post="{% url 'oef:entries_by_question' %}"
|
||||
hx-target="next .result"
|
||||
_="on click toggle @disabled until htmx:afterOnLoad then remove me"
|
||||
>View exams</button>
|
||||
<span class="result"></span>
|
||||
<button
|
||||
hx-post="{% url 'oef:questions_sym' %}"
|
||||
hx-target="next .results-sym"
|
||||
{% comment %} _="on click toggle @disabled until htmx:afterOnLoad then remove me" {% endcomment %}
|
||||
>View similar</button>
|
||||
<span class="results-sym"></span>
|
||||
>View similar</button>
|
||||
<span class="results-sym"></span>
|
||||
|
||||
</form>
|
||||
<button class="btn btn-sm" _="on click set #question1.value to the title of the previous <pre/>">
|
||||
Diff1
|
||||
</button>
|
||||
<button class="btn btn-sm" _="on click set #question2.value to the title of the previous <pre/> then go to #question2 ">
|
||||
Diff2
|
||||
</button>
|
||||
<button class="btn btn-sm" type="button"
|
||||
_="on click set q to the title of the previous <pre/> then log q then set el to `<li class='sidebar-item'><pre>${q}</pre></li>` then log el then put el at end of #sidebar-list then
|
||||
js
|
||||
new bootstrap.Offcanvas(document.getElementById('offcanvasExample')).show();
|
||||
end
|
||||
">
|
||||
Add to sidebar
|
||||
</button>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<button class="btn btn-sm" type="button" _="on click set #question1.value to the title of the previous <pre/>">
|
||||
Diff1
|
||||
</button>
|
||||
<button class="btn btn-sm" type="button" _="on click set #question2.value to the title of the previous <pre/> then go to #question2 ">
|
||||
Diff2
|
||||
</button>
|
||||
<button class="btn btn-sm" type="button"
|
||||
_="on click set q to the title of the previous <pre/> then log q then set el to `<li class='sidebar-item'><pre>${q}</pre></li>` then log el then put el at end of #sidebar-list then
|
||||
js
|
||||
new bootstrap.Offcanvas(document.getElementById('offcanvasExample')).show();
|
||||
end
|
||||
">
|
||||
Add to sidebar
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm" type="button"
|
||||
hx-post="{% url 'oef:entries_by_question_codes' %}"
|
||||
hx-target="#sidebar-codes"
|
||||
hx-swap="beforeend"
|
||||
_="on click toggle @disabled until htmx:afterOnLoad then remove me then
|
||||
js
|
||||
new bootstrap.Offcanvas(document.getElementById('offcanvasExample')).show();
|
||||
end
|
||||
"
|
||||
>Add codes to sidebar</button>
|
||||
<input type="text" class="format-name" placeholder="format name" style="display:none">
|
||||
<button
|
||||
class="btn btn-sm save-format-button" type="button" style="display:none"
|
||||
hx-post="{% url 'oef:formats_save' %}"
|
||||
>Save format</button>
|
||||
<button class="btn btn-sm" type="button"
|
||||
_="on click show previous .save-format-button then show previous .format-name then hide me">Save format</button>
|
||||
</form>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<div>Diff:</div>
|
||||
<form>
|
||||
<textarea id="question1" name="question1" cols=40 rows=10></textarea>
|
||||
<textarea id="question2" name="question2" cols=40 rows=10></textarea>
|
||||
<button
|
||||
hx-post='{% url "oef:questions_diff" %}'
|
||||
hx-target="#diff-results">Diff</button>
|
||||
<br/>
|
||||
<button type="button" style="font:inherit;font-size:.8em;background:#3465a4;color:white;border:none;padding: 0 .4em; border-radius: .4em" _="on click
|
||||
writeText(#question1.value) on navigator.clipboard
|
||||
put 'copied!' into me
|
||||
wait 1s
|
||||
put 'copy1' into me">copy1</button>
|
||||
<button type="button" style="font:inherit;font-size:.8em;background:#3465a4;color:white;border:none;padding: 0 .4em; border-radius: .4em" _="on click
|
||||
writeText(#question2.value) on navigator.clipboard
|
||||
put 'copied!' into me
|
||||
wait 1s
|
||||
put 'copy2' into me">copy2</button>
|
||||
<button type="button" style="font:inherit;font-size:.8em;background:#3465a4;color:white;border:none;padding: 0 .4em; border-radius: .4em" _="on click
|
||||
repeat for pre in .pre-question
|
||||
if #question1.value is pre.title
|
||||
then go to pre then break
|
||||
">go1</button>
|
||||
<button type="button" style="font:inherit;font-size:.8em;background:#3465a4;color:white;border:none;padding: 0 .4em; border-radius: .4em" _="on click
|
||||
repeat for pre in .pre-question
|
||||
if #question2.value is pre.title
|
||||
then go to pre then break
|
||||
">go2</button>
|
||||
<br/>results
|
||||
<span id="diff-results"></span>
|
||||
</form>
|
||||
<div>Diff:</div>
|
||||
<form>
|
||||
<textarea id="question1" name="question1" cols=40 rows=10></textarea>
|
||||
<textarea id="question2" name="question2" cols=40 rows=10></textarea>
|
||||
<button
|
||||
hx-post='{% url "oef:questions_diff" %}'
|
||||
hx-target="#diff-results">Diff</button>
|
||||
<br/>
|
||||
<button type="button" style="font:inherit;font-size:.8em;background:#3465a4;color:white;border:none;padding: 0 .4em; border-radius: .4em" _="on click
|
||||
writeText(#question1.value) on navigator.clipboard
|
||||
put 'copied!' into me
|
||||
wait 1s
|
||||
put 'copy1' into me">copy1</button>
|
||||
<button type="button" style="font:inherit;font-size:.8em;background:#3465a4;color:white;border:none;padding: 0 .4em; border-radius: .4em" _="on click
|
||||
writeText(#question2.value) on navigator.clipboard
|
||||
put 'copied!' into me
|
||||
wait 1s
|
||||
put 'copy2' into me">copy2</button>
|
||||
<button type="button" style="font:inherit;font-size:.8em;background:#3465a4;color:white;border:none;padding: 0 .4em; border-radius: .4em" _="on click
|
||||
repeat for pre in .pre-question
|
||||
if #question1.value is pre.title
|
||||
then go to pre then break
|
||||
">go1</button>
|
||||
<button type="button" style="font:inherit;font-size:.8em;background:#3465a4;color:white;border:none;padding: 0 .4em; border-radius: .4em" _="on click
|
||||
repeat for pre in .pre-question
|
||||
if #question2.value is pre.title
|
||||
then go to pre then break
|
||||
">go2</button>
|
||||
<br/>results
|
||||
<span id="diff-results"></span>
|
||||
</form>
|
||||
|
||||
|
||||
{% endblock content %}
|
||||
|
||||
|
||||
{% block css %}
|
||||
<style>
|
||||
li.question {
|
||||
border: 1px solid white;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
li.question {
|
||||
border: 1px solid white;
|
||||
}
|
||||
.format-name {
|
||||
color: blue;
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
|
||||
{% endblock css %}
|
||||
|
||||
@@ -36,6 +36,9 @@ urlpatterns = [
|
||||
path(
|
||||
"entries/entries_by_question", views.entries_by_question, name="entries_by_question"
|
||||
),
|
||||
path(
|
||||
"entries/entries_by_question/codes", views.entries_by_question_codes, name="entries_by_question_codes"
|
||||
),
|
||||
path(
|
||||
"entries/<int:pk>/update", views.EntryUpdateView.as_view(), name="entry_update"
|
||||
),
|
||||
@@ -51,5 +54,8 @@ urlpatterns = [
|
||||
path(
|
||||
"formats/<int:pk>/apply", views.formats_apply, name="formats_apply"
|
||||
),
|
||||
path(
|
||||
"formats/save", views.formats_save, name="formats_save"
|
||||
),
|
||||
|
||||
]
|
||||
+44
-2
@@ -29,7 +29,7 @@ class FormatsCreateView(CreateView):
|
||||
class FormatsUpdateView(UpdateView):
|
||||
model = Formats
|
||||
template_name_suffix = "_update_form"
|
||||
fields = ['name', 'format', 'inherits']
|
||||
fields = ['name', 'format', 'specialties', 'inherits']
|
||||
|
||||
class EntryTableView(SingleTableMixin, FilterView):
|
||||
model = Entry
|
||||
@@ -96,7 +96,16 @@ def questions(request):
|
||||
|
||||
questions = sorted(questions, key=lambda x: len(x))
|
||||
|
||||
return render(request, "oef/questions.html", {"questions": questions})
|
||||
questions_and_formats = []
|
||||
|
||||
for question in questions:
|
||||
try:
|
||||
format = Formats.objects.get(format=question)
|
||||
except Formats.DoesNotExist:
|
||||
format = None
|
||||
questions_and_formats.append((question, format))
|
||||
|
||||
return render(request, "oef/questions.html", {"questions": questions, "questions_and_formats": questions_and_formats})
|
||||
|
||||
def entries_by_question(request):
|
||||
|
||||
@@ -108,6 +117,16 @@ def entries_by_question(request):
|
||||
|
||||
return HttpResponse("Please provide a question")
|
||||
|
||||
def entries_by_question_codes(request):
|
||||
|
||||
if request.method == "POST":
|
||||
question = request.POST.get("question")
|
||||
entries = Entry.objects.filter(questions=question)
|
||||
|
||||
return render(request, "oef/entries_by_question_codes.html", {"entries": entries})
|
||||
|
||||
return HttpResponse("Please provide a question")
|
||||
|
||||
def questions_diff(request):
|
||||
if request.method == "POST":
|
||||
question1 = request.POST.get("question1", False)
|
||||
@@ -143,3 +162,26 @@ def questions_sym(request):
|
||||
|
||||
|
||||
return HttpResponse("Please provide a question set")
|
||||
|
||||
|
||||
def formats_save(request):
|
||||
|
||||
if request.method == "POST":
|
||||
question = request.POST.get("question")
|
||||
format_name = request.POST.get("format_name")
|
||||
|
||||
if not question:
|
||||
return HttpResponse("Please provide a question")
|
||||
|
||||
if Formats.objects.filter(name=format_name).exists():
|
||||
return HttpResponse("Format name already exists")
|
||||
|
||||
if Formats.objects.filter(format=question).exists():
|
||||
return HttpResponse("Format questions already exists")
|
||||
|
||||
Formats.objects.create(name="format_name", format=question)
|
||||
|
||||
return HttpResponse("Format saved")
|
||||
|
||||
|
||||
return HttpResponse("Please provide a question")
|
||||
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 5.0.2 on 2024-10-09 20:39
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('physics', '0014_rename_rapid_examquestiondetail_question'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='exam',
|
||||
name='markers',
|
||||
field=models.ManyToManyField(blank=True, help_text='Authorised markers for the exam', related_name='physics_exam_markers', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 5.0.2 on 2024-10-09 20:39
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rapids', '0012_alter_exam_markers'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='exam',
|
||||
name='markers',
|
||||
field=models.ManyToManyField(blank=True, help_text='Authorised markers for the exam', related_name='rapid_exam_markers', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 5.0.2 on 2024-10-09 20:39
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('sbas', '0014_rename_rapid_examquestiondetail_question'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='exam',
|
||||
name='markers',
|
||||
field=models.ManyToManyField(blank=True, help_text='Authorised markers for the exam', related_name='sba_exam_markers', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
Reference in New Issue
Block a user