initial rcr platform commit

This commit is contained in:
Ross
2023-11-06 09:08:50 +00:00
parent 0d852bc752
commit bbcfe7d80c
16 changed files with 361 additions and 0 deletions
+1
View File
@@ -49,6 +49,7 @@ INSTALLED_APPS = [
"sbas",
"wally",
"atlas",
"rcr",
"reversion",
"debug_toolbar",
"django_tables2",
+1
View File
@@ -63,6 +63,7 @@ urlpatterns = [
path("sbas/", include("sbas.urls"), name="sbas"),
path("generic/", include("generic.urls"), name="generic"),
path("atlas/", include("atlas.urls"), name="atlas"),
path("rcr/", include("rcr.urls"), name="rcr"),
path(
"accounts/check_users", views.accounts_check_users, name="accounts_check_users"
),
View File
+9
View File
@@ -0,0 +1,9 @@
from django.contrib import admin
# Register your models here.
from rcr.models import Item, Category, Level
admin.site.register(Item)
admin.site.register(Category)
admin.site.register(Level)
+6
View File
@@ -0,0 +1,6 @@
from django.apps import AppConfig
class RcrConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'rcr'
+24
View File
@@ -0,0 +1,24 @@
from django import forms
from django.contrib.admin import widgets
from django.forms import (
BaseInlineFormSet,
Form,
HiddenInput,
ModelForm,
ModelMultipleChoiceField,
ModelChoiceField,
ChoiceField,
CharField,
ValidationError,
modelformset_factory,
CheckboxSelectMultiple
)
from rcr.models import Item, Category, Level
class ItemForm(ModelForm):
class Meta:
model = Item
exclude = ["rcr_platform_id", "name"]
#fields = ["category", "level"]
+40
View File
@@ -0,0 +1,40 @@
# Generated by Django 4.1.4 on 2023-11-04 09:48
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Category',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
],
),
migrations.CreateModel(
name='Level',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
],
),
migrations.CreateModel(
name='Item',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200)),
('rcr_platform_id', models.CharField(max_length=255)),
('completed', models.BooleanField(default=False)),
('category', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='rcr.category')),
('level', models.ManyToManyField(to='rcr.level')),
],
),
]
View File
+40
View File
@@ -0,0 +1,40 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
# Create your models here.
class Item(models.Model):
class LevelChoices(models.TextChoices):
NONE = "", _("None")
PART_1 = "P1", _("FRCR Part 1")
PART_2 = "P2", _("FRCR Part 2")
POST_GEN = "GEN", _("Post FRCR Generalist")
POST_SPEC = "SPEC", _("Post FRCR Specialist")
name = models.CharField(max_length=200)
rcr_platform_id = models.CharField(max_length=255)
category = models.ForeignKey("Category", on_delete=models.SET_NULL, null=True, blank=True)
level = models.ManyToManyField("Level", blank=True)
completed = models.BooleanField(default=False)
def __str__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
class Level(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
+117
View File
@@ -0,0 +1,117 @@
<!DOCTYPE HTML>
{% load static %}
{% load django_htmx %}
{% load crispy_forms_tags %}
{% load auth_extras %}
<html>
<head>
<title>
{% block title %}
RCR Platform Migration
{% endblock %}
</title>
{% comment %} <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" /> {% endcomment %}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link href="{% static 'css/widgets.css' %}" type="text/css" media="all" rel="stylesheet">
<link rel="stylesheet" href="{% static 'css/dicomViewer.css' %}">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.css" integrity="sha512-6S2HWzVFxruDlZxI3sXOZZ4/eJ8AcxkQH1+JjSe/ONCEqR9L4Ysq5JdT5ipqtzU7WHalNwzwBv+iE51gNHJNqQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'favicon/apple-touch-icon.png' %}">
<link rel="icon" type="image/png" sizes="32x32" href="{% static 'favicon/favicon-32x32.png' %}">
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'favicon/favicon-16x16.png' %}">
<link rel="manifest" href="{% static 'favicon/site.webmanifest' %}">
<link rel="mask-icon" href="{% static 'favicon/safari-pinned-tab.svg' %}" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<link href="/static/css/widgets.css" type="text/css" media="all" rel="stylesheet">
<link href="/static/admin/css/vendor/select2/select2.min.css" type="text/css" media="screen" rel="stylesheet">
<link href="/static/admin/css/autocomplete.css" type="text/css" media="screen" rel="stylesheet">
<link href="/static/autocomplete_light/select2.css" type="text/css" media="screen" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/md5.js"></script>
{% comment %} <script src="https://unpkg.com/alpinejs" defer></script> {% endcomment %}
<script src="https://unpkg.com/hyperscript.org@0.9.7"></script>
<script src="https://unpkg.com/htmx.org@1.8.5/dist/htmx.min.js" defer></script>
{% django_htmx_script %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="{% static 'admin/js/core.js' %}"></script>
<script src="{% static 'admin/js/SelectBox.js' %}"></script>
<script src="{% static 'admin/js/SelectFilter2.js' %}"></script>
<script src="{% static 'jsi18n.js' %}"></script>
<script src="{% static 'admin/js/vendor/select2/select2.full.js' %}"></script>
<script src="{% static 'autocomplete_light/autocomplete_light.min.js' %}"></script>
<script src="{% static 'tesseract.min.js' %}"></script>
<script src="{% static 'autocomplete_light/select2.min.js' %}"></script>
<script src="{% static 'autocomplete_light/i18n/en.js' %}"></script>
<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-AMS-MML_HTMLorMML"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dexie/3.0.3/dexie.min.js" integrity="sha512-aEtNzq8X5E0ambgeM68H174SOXaANJ6wDqJ0TuVIx4R2J4fRdUA0nLzx0faA1mmViqb+r0VX7cOXkskxyJENUA==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5sortable/0.10.0/html5sortable.min.js" integrity="sha512-tBlVMq89XaEC9iU5LyRjP2Vxs8SmVhEHGbv2Co6SbGa14Wsxy2qZN0jadrN+Xn5AifORaUbvZcG21/ExcNfWDA==" crossorigin="anonymous"></script>
<script src="{% static 'tesseract.min.js' %}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.js" integrity="sha512-lbwH47l/tPXJYG9AcFNoJaTMhGvYWhVM9YI43CT+uteTRRaiLCui8snIgyAN8XWgNjNhCqlAUdzZptso6OCoFQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<script src="{% static 'js/cornerstone/hammer.js' %}"></script>
<script src="{% static 'js/cornerstone/cornerstone.min.js' %}"></script>
<script src="{% static 'js/cornerstone/dicomParser.min.js' %}"></script>
<script src="{% static 'js/cornerstone/cornerstoneMath.min.js' %}"></script>
<script src="{% static 'js/cornerstone/cornerstoneTools.min.js' %}"></script>
<script src="{% static 'js/cornerstone/cornerstoneWebImageLoader.min.js' %}"></script>
<script src="{% static 'js/cornerstone/cornerstoneWADOImageLoader.min.js' %}"></script>
<script src="{% static 'js/cornerstone/cornerstone-base64-image-loader.umd.js' %}"></script>
<script src="{% static 'js/anatomy.js' %}" defer="defer" type="module"></script>
{% block js %}
{% endblock %}
<link rel="stylesheet" href="{% static 'css/anatomy.css' %}">
{% block css %}
{% endblock %}
</head>
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
<div class="main-nav-header">
<span id="" class="top-bar-link">
<a href="{% url 'rcr:radiology_index_view' %}">Index</a>
</span>
{% if request.user.is_staff %}
<span id="admin-link" class="top-bar-link">
<a href="{% url 'admin:index' %}">Admin</a>
</span>
{% endif %}
<span id="index-link" class="top-bar-link">
<a href="{% url 'home' %}">Home</a>
</span>
</div>
<div class="content container">
{% block navigation %}
{% endblock %}
<div class="row clear-both">
<div class="col-md-12">
{% block content %}
{% endblock %}
</div>
</div>
</div>
<footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
<div class="col-md-4 d-flex align-items-center">
<a href="/" class="mb-3 me-2 mb-md-0 text-muted text-decoration-none lh-1">
<svg class="bi" width="30" height="24"><use xlink:href="#bootstrap"></use></svg>
</a>
<span class="text-muted">PenraCourses</span>
</div>
<ul class="nav col-md-4 justify-content-end list-unstyled d-flex">
<li class="ms-3"><a class="text-muted" href="{% url 'privacy' %}">Privacy</a></li>
<li class="ms-3"><a class="text-muted" href="{% url 'cookie_consent_cookie_group_list' %}">Cookies</a></li>
</ul>
</footer>
</body>
</html>
+19
View File
@@ -0,0 +1,19 @@
{% extends 'rcr/base.html' %}
{% block content %}
<ul>
{% for item in items %}
<li>
{{item.name}} / {{item.rcr_platform_id}}<br />
<a href="{% url 'rcr:radiology_detail_view' item.pk %}">view</a>
<a href="{% url 'rcr:radiology_update_view' item.pk %}">edit</a>
</li>
{% endfor %}
</ul>
TEST
{% endblock %}
+7
View File
@@ -0,0 +1,7 @@
{% extends 'rcr/base.html' %}
{% block content %}
<h2>Item: {{object.name}}</h2>
<details><summary> </summary>
</details>
{% endblock %}
+15
View File
@@ -0,0 +1,15 @@
{% extends 'rcr/base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<h2>Item: {{object.name}}</h2>
{% comment %} {% if request.user.is_superuser %}
(<a href="{% url 'admin:auth_user_change' object.id %}" title="Edit the user using the admin interface">Admin Edit</a>)
{% endif %} {% endcomment %}
<form method="post">{% csrf_token %}
{{ form|crispy }}
<input type="submit" value="Update">
</form>
<details><summary> </summary>
</details>
{% endblock %}
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+18
View File
@@ -0,0 +1,18 @@
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 = "rcr"
urlpatterns = [
path("radiology/", views.radiology_index, name="radiology_index_view"),
path("radiology/item/<int:pk>/", views.ItemDetailView.as_view(), name="radiology_detail_view"),
path("radiology/item/next/update", views.ItemUpdateNextView.as_view(), name="radiology_update_next_view"),
path("radiology/item/<int:pk>/update", views.ItemUpdateView.as_view(), name="radiology_update_view"),
]
+61
View File
@@ -0,0 +1,61 @@
from typing import Any
from django.db import models
from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic.edit import UpdateView
from django.views.generic.detail import DetailView
from rcr.models import Item
from rcr.forms import ItemForm
# Create your views here.
def radiology_index(request):
items = Item.objects.all()
return render(
request,
"rcr/index.html",
{
"items": items
},
)
class ItemUpdateView(UpdateView):
model = Item
form_class = ItemForm
template_name = "rcr/item_update.html"
#excludes = ["rcr_platform_id"]
#fields = ["category", "level"]
class ItemUpdateNextView(UpdateView):
model = Item
form_class = ItemForm
template_name = "rcr/item_update.html"
def get_object(self):
obj = Item.objects.filter(completed=False).first()
#~if not obj:
#~ return reverse_lazy("rcr:radiology_index_view")
return obj
print("test")
return super().get_object()
#def get
def get_success_url(self) -> str:
return reverse_lazy("rcr:radiology_update_next_view")
class ItemDetailView(DetailView):
model = Item
#template_name = "TEMPLATE_NAME"
#excludes = ["rcr_platform_id"]