start oef

This commit is contained in:
Ross
2024-10-07 17:10:39 +01:00
parent 3f5f39c41c
commit 1e55d195e9
24 changed files with 468 additions and 0 deletions
View File
+9
View File
@@ -0,0 +1,9 @@
from django.contrib import admin
# Register your models here.
from .models import Entry, Formats
admin.site.register(Entry)
admin.site.register(Formats)
+6
View File
@@ -0,0 +1,6 @@
from django.apps import AppConfig
class OefConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'oef'
+18
View File
@@ -0,0 +1,18 @@
import django_filters
from .models import Entry
from django.contrib.auth.models import User
from django.db.models import Q
class EntryFilter(django_filters.FilterSet):
class Meta:
model = Entry
fields = {
"modality": ["icontains"],
"exam_code": ["icontains"],
"exam_name": ["icontains"],
"questions": ["icontains"],
"comments": ["icontains"],
}
View File
View File
+70
View File
@@ -0,0 +1,70 @@
from pathlib import Path
from django.core.management.base import BaseCommand, CommandError
import argparse
from oef.models import Entry
from bs4 import BeautifulSoup
class Command(BaseCommand):
help = "Imports the RCR spreadsheet"
def add_arguments(self, parser):
# parser.add_argument("poll_ids", nargs="+", type=int)
parser.add_argument('--file', type=argparse.FileType('r'))
def handle(self, *args, **options):
#with open(options["file"]) as f:
soup = BeautifulSoup(options["file"], "html.parser")
Entry.objects.all().delete()
rows = 0
for row in soup.find_all("tr"):
if rows > 0:
entry.questions = entry.questions + "\n" + row.find_all("td")[0].text
rows = rows - 1
if rows == 0:
entry.save()
continue
cells = row.find_all("td")
if cells[0].text == "Modality":
continue
entry = Entry()
entry.modality = cells[0].text
entry.exam_code = cells[1].text
entry.exam_name = cells[2].text
entry.questions = cells[3].text
entry.oef_name = cells[4].text
entry.comments = cells[5].text
if cells[0].has_attr("rowspan"):
rows = int(cells[0]["rowspan"]) - 1
else:
entry.save()
#Entry.objects.all().delete()
#for row in soup.find_all("tr"):
# cells = row.find_all("td")
# if len(cells) == 6:
# entry = Entry()
# entry.modality = cells[0].text
# entry.exam_code = cells[1].text
# entry.exam_name = cells[2].text
# entry.questions = cells[3].text
# #entry.
# entry.comments = cells[5].text
# entry.save()
# self.stdout.write(
# self.style.SUCCESS(f"Entry added: {entry.pk}/{entry.exam_name}")
# )
# else:
# self.stdout.write(
# self.style.WARNING(f"Skipping row: {row}")
# )
+36
View File
@@ -0,0 +1,36 @@
# Generated by Django 5.0.2 on 2024-10-07 13:30
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Entry',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('modality', models.CharField(max_length=200)),
('exam_code', models.CharField(max_length=50)),
('exam_name', models.CharField(max_length=200)),
('questions', models.TextField()),
('questions_original', models.TextField()),
('comments', models.TextField()),
],
),
migrations.CreateModel(
name='Formats',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200)),
('format', models.TextField()),
('inherits', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='oef.formats')),
],
),
]
@@ -0,0 +1,23 @@
# Generated by Django 5.0.2 on 2024-10-07 15:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('oef', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='entry',
name='oef_name',
field=models.CharField(blank=True, max_length=200),
),
migrations.AlterField(
model_name='entry',
name='comments',
field=models.TextField(blank=True),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 5.0.2 on 2024-10-07 15:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('oef', '0002_entry_oef_name_alter_entry_comments'),
]
operations = [
migrations.AlterField(
model_name='formats',
name='format',
field=models.TextField(blank=True),
),
]
View File
+61
View File
@@ -0,0 +1,61 @@
from django.db import models
from django.urls import reverse
# Create your models here.
class Entry(models.Model):
modality = models.CharField(max_length=200)
exam_code = models.CharField(max_length=50)
exam_name = models.CharField(max_length=200)
questions = models.TextField()
questions_original = models.TextField()
oef_name = models.CharField(max_length=200, blank=True)
comments = models.TextField(blank=True)
#format = models.ForeignKey('Formats', on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return self.exam_name
def get_absolute_url(self):
return reverse("oef:entry_update", kwargs={"pk": self.pk})
def clean(self) -> None:
self.questions = self.questions.replace("\r\n", "\n")
return super().clean()
def save(self, *args, **kwargs):
self.questions = self.questions.replace("\r\n", "\n")
return super().save(*args, **kwargs)
class Formats(models.Model):
name = models.CharField(max_length=200)
format = models.TextField(blank=True)
inherits = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("oef:format_update", kwargs={"pk": self.pk})
def clean(self) -> None:
self.format = self.format.replace("\r\n", "\n")
return super().clean()
def save(self, *args, **kwargs):
self.format = self.format.replace("\r\n", "\n")
return super().save(*args, **kwargs)
def get_format(self):
formats = [self.format]
while self.inherits:
self = self.inherits
formats.append(self.format)
formats.reverse()
return "\n".join(formats)
Executable
+35
View File
@@ -0,0 +1,35 @@
import django_tables2 as tables
from django_tables2.utils import A
from generic.tables import SeriesImageColumn
from .models import (
Entry,
Formats
)
from django.utils.html import format_html
class EntryTable(tables.Table):
edit = tables.LinkColumn(
"oef:entry_update", text="Edit", args=[A("pk")], orderable=False
)
class Meta:
model = Entry
template_name = "django_tables2/bootstrap4.html"
fields = (
"modality",
"exam_code",
"exam_name",
"questions",
"comments",
)
def render_questions(self, value):
return format_html("<pre>{}</pre>", value)
+9
View File
@@ -0,0 +1,9 @@
{% extends 'base.html' %}
{% block css %}
{% endblock %}
{% block navigation %}
<a href="{% url 'oef:entry_table_view' %}">Entries</a> /
<a href="{% url 'oef:formats_view' %}">Formats</a> /
{% endblock %}
+25
View File
@@ -0,0 +1,25 @@
{% extends 'oef/base.html' %}
{% block css %}
{% endblock %}
{% block content %}
<div id="view-filter-options">
<details><summary>
<h3>Filter Entries</h3>
</summary>
<form action="" method="get">
{{ filter.form }}
<input class="btn btn-primary btn-sm mt-1 mb-1" type="submit" />
</form>
</details>
</div>
{% autoescape off %}
{% load render_table from django_tables2 %}
{% render_table table %}
{% endautoescape %}
{% endblock %}
+8
View File
@@ -0,0 +1,8 @@
{% extends 'oef/base.html' %}
{% block content %}
<form method="post">{% csrf_token %}
{{ form }}
<input type="submit" value="Update">
</form>
{% endblock content %}
+33
View File
@@ -0,0 +1,33 @@
{% extends 'oef/base.html' %}
{% block content %}
<h2>Formats Search</h2>
The format {{format.name}} exists in the following {{ entries.count }} entries:
<pre>
{{ format.get_format}}
</pre>
<ul>
{% for entry, text in entry_list %}
<li class=" {% if not text %}no-extra{% endif %}">{{ entry.exam_name }} (<a href='{% url "oef:entry_update" entry.pk %}'>edit</a>)<br/> <pre>{{text}}<pre></li>
{% endfor %}
</ul>
{% endblock content %}
{% block css %}
<style type="text/css">
.no-extra {
color: blue;
}
</style>
{% endblock %}
@@ -0,0 +1,8 @@
{% extends 'oef/base.html' %}
{% block content %}
<form method="post">{% csrf_token %}
{{ form }}
<input type="submit" value="Update">
</form>
{% endblock content %}
+22
View File
@@ -0,0 +1,22 @@
{% extends 'oef/base.html' %}
{% block content %}
<h2>Formats</h2>
<a href="{% url 'oef:format_create' %}">Create a new format</a>
<ul>
{% for format in formats %}
<li>
<a href="{% url 'oef:format_update' format.id %}">{{ format.name }}</a>
<a href="{% url 'oef:formats_apply' format.id %}">apply</a>
</li>
{% endfor %}
</ul>
{% endblock content %}
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+33
View File
@@ -0,0 +1,33 @@
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from django.views.generic import TemplateView
from . import views
app_name = "oef"
urlpatterns = [
path(
"entries", views.EntryTableView.as_view(), name="entry_table_view"
),
path(
"formats", views.formats_view, name="formats_view"
),
path(
"formats/create", views.FormatsCreateView.as_view(), name="format_create"
),
path(
"entries/<int:pk>/update", views.EntryUpdateView.as_view(), name="entry_update"
),
path(
"formats/<int:pk>/update", views.FormatsUpdateView.as_view(), name="format_update"
),
path(
"formats/<int:pk>/apply", views.formats_apply, name="formats_apply"
),
]
+49
View File
@@ -0,0 +1,49 @@
from django.shortcuts import get_object_or_404, render
from django.views.generic.edit import UpdateView, CreateView
from .models import Entry, Formats
# Create your views here.
from .tables import EntryTable
from .filters import EntryFilter
from django_filters.views import FilterView
from django_tables2 import SingleTableView, SingleTableMixin
class EntryUpdateView(UpdateView):
model = Entry
template_name = "oef/entry_update_view.html"
fields = ['modality', 'exam_code', 'exam_name', 'questions', 'comments']
class FormatsCreateView(CreateView):
model = Formats
template_name_suffix = "_update_form"
fields = ['name', 'format', 'inherits']
class FormatsUpdateView(UpdateView):
model = Formats
template_name_suffix = "_update_form"
fields = ['name', 'format', 'inherits']
class EntryTableView(SingleTableMixin, FilterView):
model = Entry
table_class = EntryTable
template_name = "oef/entry_table.html"
filterset_class = EntryFilter
def formats_view(request):
formats = Formats.objects.all()
return render(request, "oef/formats_view.html", {"formats": formats})
def formats_apply(request, pk):
format = get_object_or_404(Formats, pk=pk)
search_text = format.get_format()
entries = Entry.objects.filter(questions__icontains=search_text)
entry_list = []
for entry in entries:
entry_list.append((entry, entry.questions.replace(search_text, "")))
return render(request, "oef/formats_apply.html", {"format": format, "entry_list": entry_list, "entries": entries})
+1
View File
@@ -51,6 +51,7 @@ INSTALLED_APPS = [
"atlas", "atlas",
"rcr", "rcr",
"rota", "rota",
"oef",
"reversion", "reversion",
"debug_toolbar", "debug_toolbar",
"django_tables2", "django_tables2",
+1
View File
@@ -66,6 +66,7 @@ urlpatterns = [
path("atlas/", include("atlas.urls"), name="atlas"), path("atlas/", include("atlas.urls"), name="atlas"),
path("rcr/", include("rcr.urls"), name="rcr"), path("rcr/", include("rcr.urls"), name="rcr"),
path("rota/", include("rota.urls"), name="rota"), path("rota/", include("rota.urls"), name="rota"),
path("oef/", include("oef.urls"), name="oef"),
path( path(
"accounts/check_users", views.accounts_check_users, name="accounts_check_users" "accounts/check_users", views.accounts_check_users, name="accounts_check_users"
), ),