endoreg-db 0.5.3__py3-none-any.whl → 0.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of endoreg-db might be problematic. Click here for more details.
- endoreg_db/admin.py +90 -1
- endoreg_db/case_generator/case_generator.py +159 -0
- endoreg_db/case_generator/lab_sample_factory.py +33 -0
- endoreg_db/case_generator/utils.py +30 -0
- endoreg_db/data/__init__.py +50 -4
- endoreg_db/data/ai_model/data.yaml +7 -0
- endoreg_db/data/{label → ai_model_label}/label/data.yaml +27 -1
- endoreg_db/data/ai_model_label/label-set/data.yaml +21 -0
- endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +5 -0
- endoreg_db/data/ai_model_video_segmentation_label/base_segmentation.yaml +176 -0
- endoreg_db/data/ai_model_video_segmentation_labelset/data.yaml +20 -0
- endoreg_db/data/center/data.yaml +35 -5
- endoreg_db/data/contraindication/bleeding.yaml +11 -0
- endoreg_db/data/distribution/numeric/data.yaml +14 -0
- endoreg_db/data/endoscope/data.yaml +93 -0
- endoreg_db/data/examination_indication/endoscopy.yaml +8 -0
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +8 -0
- endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +101 -0
- endoreg_db/data/finding/data.yaml +141 -0
- endoreg_db/data/finding_intervention/endoscopy.yaml +138 -0
- endoreg_db/data/finding_intervention_type/endoscopy.yaml +15 -0
- endoreg_db/data/finding_location_classification/colonoscopy.yaml +46 -0
- endoreg_db/data/finding_location_classification_choice/colonoscopy.yaml +240 -0
- endoreg_db/data/finding_morphology_classification/colonoscopy.yaml +48 -0
- endoreg_db/data/finding_morphology_classification_choice/colon_lesion_circularity_default.yaml +34 -0
- endoreg_db/data/finding_morphology_classification_choice/colon_lesion_nice.yaml +20 -0
- endoreg_db/data/finding_morphology_classification_choice/colon_lesion_paris.yaml +65 -0
- endoreg_db/data/finding_morphology_classification_choice/colon_lesion_planarity_default.yaml +56 -0
- endoreg_db/data/finding_morphology_classification_choice/colon_lesion_surface_intact_default.yaml +39 -0
- endoreg_db/data/finding_morphology_classification_choice/colonoscopy_size.yaml +57 -0
- endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +79 -0
- endoreg_db/data/finding_type/data.yaml +30 -0
- endoreg_db/data/gender/data.yaml +17 -0
- endoreg_db/data/lab_value/cardiac_enzymes.yaml +7 -1
- endoreg_db/data/lab_value/coagulation.yaml +6 -1
- endoreg_db/data/lab_value/electrolytes.yaml +39 -1
- endoreg_db/data/lab_value/gastrointestinal_function.yaml +12 -0
- endoreg_db/data/lab_value/hematology.yaml +17 -2
- endoreg_db/data/lab_value/hormones.yaml +6 -0
- endoreg_db/data/lab_value/lipids.yaml +12 -3
- endoreg_db/data/lab_value/misc.yaml +5 -2
- endoreg_db/data/lab_value/renal_function.yaml +2 -1
- endoreg_db/data/lx_client_tag/base.yaml +54 -0
- endoreg_db/data/lx_client_type/base.yaml +30 -0
- endoreg_db/data/lx_permission/base.yaml +24 -0
- endoreg_db/data/lx_permission/endoreg.yaml +52 -0
- endoreg_db/data/medication_indication/anticoagulation.yaml +44 -49
- endoreg_db/data/names_first/first_names.yaml +51 -0
- endoreg_db/data/names_last/last_names.yaml +51 -0
- endoreg_db/data/network_device/data.yaml +30 -0
- endoreg_db/data/organ/data.yaml +29 -0
- endoreg_db/data/pdf_type/data.yaml +2 -1
- endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +4 -0
- endoreg_db/forms/__init__.py +3 -1
- endoreg_db/forms/examination_form.py +11 -0
- endoreg_db/forms/patient_finding_intervention_form.py +19 -0
- endoreg_db/forms/patient_form.py +26 -0
- endoreg_db/management/commands/__init__.py +0 -0
- endoreg_db/management/commands/load_ai_model_data.py +57 -23
- endoreg_db/management/commands/load_ai_model_label_data.py +59 -0
- endoreg_db/management/commands/load_base_db_data.py +160 -118
- endoreg_db/management/commands/{load_endoscope_type_data.py → load_contraindication_data.py} +3 -7
- endoreg_db/management/commands/load_disease_data.py +29 -7
- endoreg_db/management/commands/load_endoscope_data.py +68 -0
- endoreg_db/management/commands/load_examination_indication_data.py +65 -0
- endoreg_db/management/commands/load_finding_data.py +171 -0
- endoreg_db/management/commands/load_lab_value_data.py +3 -3
- endoreg_db/management/commands/load_lx_data.py +64 -0
- endoreg_db/management/commands/load_medication_data.py +83 -21
- endoreg_db/management/commands/load_name_data.py +37 -0
- endoreg_db/management/commands/{load_endoscopy_processor_data.py → load_organ_data.py} +7 -9
- endoreg_db/migrations/0001_initial.py +1206 -728
- endoreg_db/migrations/0002_alter_frame_image_alter_rawframe_image.py +23 -0
- endoreg_db/migrations/0003_alter_frame_image_alter_rawframe_image.py +23 -0
- endoreg_db/migrations/0004_alter_rawvideofile_file_alter_video_file.py +25 -0
- endoreg_db/migrations/0005_rawvideofile_frame_count_and_more.py +33 -0
- endoreg_db/migrations/0006_frame_extracted_rawframe_extracted.py +23 -0
- endoreg_db/migrations/0007_rename_pseudo_patient_video_patient_and_more.py +24 -0
- endoreg_db/migrations/0008_remove_reportfile_patient_examination_and_more.py +48 -0
- endoreg_db/models/__init__.py +331 -28
- endoreg_db/models/ai_model/__init__.py +1 -0
- endoreg_db/models/ai_model/ai_model.py +103 -0
- endoreg_db/models/ai_model/lightning/__init__.py +3 -0
- endoreg_db/models/ai_model/lightning/inference_dataset.py +53 -0
- endoreg_db/models/ai_model/lightning/multilabel_classification_net.py +155 -0
- endoreg_db/models/ai_model/lightning/postprocess.py +53 -0
- endoreg_db/models/ai_model/lightning/predict.py +172 -0
- endoreg_db/models/ai_model/lightning/prediction_visualizer.py +55 -0
- endoreg_db/models/ai_model/lightning/preprocess.py +68 -0
- endoreg_db/models/ai_model/lightning/run_visualizer.py +21 -0
- endoreg_db/models/ai_model/model_meta.py +232 -6
- endoreg_db/models/ai_model/model_type.py +13 -3
- endoreg_db/models/annotation/__init__.py +31 -2
- endoreg_db/models/annotation/anonymized_image_annotation.py +73 -18
- endoreg_db/models/annotation/binary_classification_annotation_task.py +94 -57
- endoreg_db/models/annotation/image_classification.py +73 -14
- endoreg_db/models/annotation/video_segmentation_annotation.py +52 -0
- endoreg_db/models/annotation/video_segmentation_labelset.py +20 -0
- endoreg_db/models/case/__init__.py +1 -0
- endoreg_db/models/{persons/patient/case → case}/case.py +4 -0
- endoreg_db/models/case_template/__init__.py +10 -1
- endoreg_db/models/case_template/case_template.py +57 -13
- endoreg_db/models/case_template/case_template_rule.py +5 -5
- endoreg_db/models/case_template/case_template_rule_value.py +19 -4
- endoreg_db/models/center/__init__.py +7 -0
- endoreg_db/models/center/center.py +31 -5
- endoreg_db/models/center/center_product.py +0 -1
- endoreg_db/models/center/center_resource.py +16 -2
- endoreg_db/models/center/center_waste.py +6 -1
- endoreg_db/models/contraindication/__init__.py +21 -0
- endoreg_db/models/data_file/__init__.py +38 -5
- endoreg_db/models/data_file/base_classes/__init__.py +6 -1
- endoreg_db/models/data_file/base_classes/abstract_frame.py +64 -15
- endoreg_db/models/data_file/base_classes/abstract_pdf.py +136 -0
- endoreg_db/models/data_file/base_classes/abstract_video.py +744 -138
- endoreg_db/models/data_file/base_classes/frame_helpers.py +17 -0
- endoreg_db/models/data_file/base_classes/prepare_bulk_frames.py +19 -0
- endoreg_db/models/data_file/base_classes/utils.py +80 -0
- endoreg_db/models/data_file/frame.py +22 -38
- endoreg_db/models/data_file/import_classes/__init__.py +4 -18
- endoreg_db/models/data_file/import_classes/raw_pdf.py +162 -90
- endoreg_db/models/data_file/import_classes/raw_video.py +239 -294
- endoreg_db/models/data_file/metadata/__init__.py +10 -0
- endoreg_db/models/data_file/metadata/pdf_meta.py +4 -0
- endoreg_db/models/data_file/metadata/sensitive_meta.py +265 -6
- endoreg_db/models/data_file/metadata/video_meta.py +116 -50
- endoreg_db/models/data_file/report_file.py +30 -63
- endoreg_db/models/data_file/video/__init__.py +6 -2
- endoreg_db/models/data_file/video/video.py +187 -16
- endoreg_db/models/data_file/video_segment.py +162 -55
- endoreg_db/models/disease.py +25 -2
- endoreg_db/models/emission/__init__.py +5 -1
- endoreg_db/models/emission/emission_factor.py +71 -6
- endoreg_db/models/event.py +51 -0
- endoreg_db/models/examination/__init__.py +6 -1
- endoreg_db/models/examination/examination.py +53 -12
- endoreg_db/models/examination/examination_indication.py +170 -0
- endoreg_db/models/examination/examination_time.py +31 -5
- endoreg_db/models/examination/examination_time_type.py +28 -4
- endoreg_db/models/examination/examination_type.py +28 -6
- endoreg_db/models/finding/__init__.py +11 -0
- endoreg_db/models/finding/finding.py +75 -0
- endoreg_db/models/finding/finding_intervention.py +60 -0
- endoreg_db/models/finding/finding_location_classification.py +94 -0
- endoreg_db/models/finding/finding_morphology_classification.py +89 -0
- endoreg_db/models/finding/finding_type.py +22 -0
- endoreg_db/models/hardware/endoscope.py +16 -0
- endoreg_db/models/hardware/endoscopy_processor.py +31 -19
- endoreg_db/models/label/label.py +35 -7
- endoreg_db/models/laboratory/lab_value.py +12 -3
- endoreg_db/models/logging/__init__.py +8 -1
- endoreg_db/models/lx/__init__.py +4 -0
- endoreg_db/models/lx/client.py +57 -0
- endoreg_db/models/lx/identity.py +34 -0
- endoreg_db/models/lx/permission.py +18 -0
- endoreg_db/models/lx/user.py +16 -0
- endoreg_db/models/medication/__init__.py +19 -1
- endoreg_db/models/medication/medication.py +7 -122
- endoreg_db/models/medication/medication_indication.py +50 -0
- endoreg_db/models/medication/medication_indication_type.py +34 -0
- endoreg_db/models/medication/medication_intake_time.py +26 -0
- endoreg_db/models/medication/medication_schedule.py +37 -0
- endoreg_db/models/network/__init__.py +7 -1
- endoreg_db/models/network/network_device.py +13 -8
- endoreg_db/models/organ/__init__.py +38 -0
- endoreg_db/models/other/__init__.py +19 -1
- endoreg_db/models/other/distribution/__init__.py +44 -0
- endoreg_db/models/other/distribution/base_value_distribution.py +20 -0
- endoreg_db/models/other/distribution/date_value_distribution.py +91 -0
- endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +32 -0
- endoreg_db/models/other/distribution/numeric_value_distribution.py +97 -0
- endoreg_db/models/other/distribution/single_categorical_value_distribution.py +22 -0
- endoreg_db/models/other/distribution.py +1 -211
- endoreg_db/models/other/material.py +4 -0
- endoreg_db/models/other/transport_route.py +2 -1
- endoreg_db/models/patient/__init__.py +24 -0
- endoreg_db/models/patient/patient_examination.py +182 -0
- endoreg_db/models/patient/patient_finding.py +143 -0
- endoreg_db/models/patient/patient_finding_intervention.py +26 -0
- endoreg_db/models/patient/patient_finding_location.py +120 -0
- endoreg_db/models/patient/patient_finding_morphology.py +166 -0
- endoreg_db/models/persons/__init__.py +29 -2
- endoreg_db/models/persons/examiner/examiner.py +48 -4
- endoreg_db/models/persons/patient/__init__.py +1 -1
- endoreg_db/models/persons/patient/patient.py +227 -54
- endoreg_db/models/persons/patient/patient_disease.py +6 -0
- endoreg_db/models/persons/patient/patient_event.py +31 -1
- endoreg_db/models/persons/patient/patient_examination_indication.py +32 -0
- endoreg_db/models/persons/patient/patient_lab_sample.py +4 -2
- endoreg_db/models/persons/patient/patient_lab_value.py +37 -16
- endoreg_db/models/persons/patient/patient_medication.py +27 -12
- endoreg_db/models/persons/patient/patient_medication_schedule.py +62 -2
- endoreg_db/models/prediction/__init__.py +7 -1
- endoreg_db/models/prediction/image_classification.py +20 -6
- endoreg_db/models/prediction/video_prediction_meta.py +151 -89
- endoreg_db/models/product/__init__.py +10 -1
- endoreg_db/models/product/product.py +15 -2
- endoreg_db/models/product/product_group.py +8 -0
- endoreg_db/models/product/product_material.py +4 -0
- endoreg_db/models/product/product_weight.py +12 -0
- endoreg_db/models/product/reference_product.py +19 -3
- endoreg_db/models/quiz/__init__.py +8 -1
- endoreg_db/models/report_reader/__init__.py +6 -1
- endoreg_db/serializers/__init__.py +1 -1
- endoreg_db/serializers/annotation.py +2 -5
- endoreg_db/serializers/frame.py +1 -5
- endoreg_db/serializers/patient.py +26 -3
- endoreg_db/serializers/prediction.py +2 -7
- endoreg_db/serializers/raw_video_meta_validation.py +13 -0
- endoreg_db/serializers/video.py +6 -13
- endoreg_db/serializers/video_segmentation.py +492 -0
- endoreg_db/templates/admin/patient_finding_intervention.html +253 -0
- endoreg_db/templates/admin/start_examination.html +12 -0
- endoreg_db/templates/timeline.html +176 -0
- endoreg_db/urls.py +173 -0
- endoreg_db/utils/__init__.py +36 -1
- endoreg_db/utils/dataloader.py +45 -19
- endoreg_db/utils/dates.py +39 -0
- endoreg_db/utils/hashs.py +122 -4
- endoreg_db/utils/names.py +74 -0
- endoreg_db/utils/parse_and_generate_yaml.py +46 -0
- endoreg_db/utils/pydantic_models/__init__.py +6 -0
- endoreg_db/utils/pydantic_models/db_config.py +57 -0
- endoreg_db/utils/validate_endo_roi.py +19 -0
- endoreg_db/utils/validate_subcategory_dict.py +91 -0
- endoreg_db/utils/video/__init__.py +13 -0
- endoreg_db/utils/video/extract_frames.py +121 -0
- endoreg_db/utils/video/transcode_videofile.py +111 -0
- endoreg_db/views/__init__.py +2 -0
- endoreg_db/views/csrf.py +7 -0
- endoreg_db/views/patient_views.py +90 -0
- endoreg_db/views/raw_video_meta_validation_views.py +38 -0
- endoreg_db/views/report_views.py +96 -0
- endoreg_db/views/video_segmentation_views.py +149 -0
- endoreg_db/views/views_for_timeline.py +46 -0
- endoreg_db/views.py +0 -3
- endoreg_db-0.6.1.dist-info/METADATA +151 -0
- endoreg_db-0.6.1.dist-info/RECORD +420 -0
- {endoreg_db-0.5.3.dist-info → endoreg_db-0.6.1.dist-info}/WHEEL +1 -1
- endoreg_db/data/active_model/data.yaml +0 -3
- endoreg_db/data/label/label-set/data.yaml +0 -18
- endoreg_db/management/commands/delete_legacy_images.py +0 -19
- endoreg_db/management/commands/delete_legacy_videos.py +0 -17
- endoreg_db/management/commands/extract_legacy_video_frames.py +0 -18
- endoreg_db/management/commands/import_legacy_images.py +0 -94
- endoreg_db/management/commands/import_legacy_videos.py +0 -76
- endoreg_db/management/commands/load_label_data.py +0 -67
- endoreg_db/migrations/0002_anonymizedimagelabel_anonymousimageannotation_and_more.py +0 -55
- endoreg_db/migrations/0003_anonymousimageannotation_original_image_url_and_more.py +0 -39
- endoreg_db/migrations/0004_alter_rawpdffile_file.py +0 -20
- endoreg_db/migrations/0005_uploadedfile_alter_rawpdffile_file_anonymizedfile.py +0 -40
- endoreg_db/migrations/0006_alter_rawpdffile_file.py +0 -20
- endoreg_db/migrations/0007_networkdevicelogentry_datetime_and_more.py +0 -43
- endoreg_db/migrations/0008_networkdevicelogentry_aglnet_ip_and_more.py +0 -28
- endoreg_db/migrations/0009_alter_networkdevicelogentry_vpn_service_status.py +0 -18
- endoreg_db/migrations/0010_remove_networkdevicelogentry_hostname.py +0 -17
- endoreg_db/models/legacy_data/__init__.py +0 -3
- endoreg_db/models/legacy_data/image.py +0 -34
- endoreg_db/models/patient_examination/__init__.py +0 -35
- endoreg_db/utils/video_metadata.py +0 -87
- endoreg_db-0.5.3.dist-info/METADATA +0 -28
- endoreg_db-0.5.3.dist-info/RECORD +0 -319
- /endoreg_db/{models/persons/patient/case → case_generator}/__init__.py +0 -0
- /endoreg_db/data/{label → ai_model_label}/label-type/data.yaml +0 -0
- /endoreg_db/data/{model_type → ai_model_type}/data.yaml +0 -0
- /endoreg_db/{data/distribution/numeric/.init → management/__init__.py} +0 -0
- /endoreg_db/management/commands/{load_report_reader_flag.py → load_report_reader_flag_data.py} +0 -0
- {endoreg_db-0.5.3.dist-info → endoreg_db-0.6.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
from typing import List
|
|
3
|
+
# Class to represent the LocationClassifications of a Finding
|
|
4
|
+
|
|
5
|
+
class FindingLocationClassificationManager(models.Manager):
|
|
6
|
+
def get_by_natural_key(self, name):
|
|
7
|
+
return self.get(name=name)
|
|
8
|
+
|
|
9
|
+
class FindingLocationClassification(models.Model):
|
|
10
|
+
name = models.CharField(max_length=100, unique=True)
|
|
11
|
+
name_de = models.CharField(max_length=100, blank=True, null=True)
|
|
12
|
+
name_en = models.CharField(max_length=100, blank=True, null=True)
|
|
13
|
+
description = models.TextField(blank=True, null=True)
|
|
14
|
+
description_de = models.TextField(blank=True, null=True)
|
|
15
|
+
description_en = models.TextField(blank=True, null=True)
|
|
16
|
+
|
|
17
|
+
# Many to many relationships:
|
|
18
|
+
findings = models.ManyToManyField('Finding', blank=True, related_name='location_classifications')
|
|
19
|
+
examinations = models.ManyToManyField('Examination', blank=True, related_name='location_classifications')
|
|
20
|
+
finding_types = models.ManyToManyField('FindingType', blank=True, related_name='location_classifications')
|
|
21
|
+
choices = models.ManyToManyField('FindingLocationClassificationChoice', blank=True, related_name='location_classifications')
|
|
22
|
+
|
|
23
|
+
objects = FindingLocationClassificationManager()
|
|
24
|
+
|
|
25
|
+
def natural_key(self):
|
|
26
|
+
return (self.name,)
|
|
27
|
+
|
|
28
|
+
def __str__(self):
|
|
29
|
+
return self.name
|
|
30
|
+
|
|
31
|
+
def get_available_findings(self):
|
|
32
|
+
from endoreg_db.models import Finding
|
|
33
|
+
available_findings:List[Finding] = [_ for _ in self.findings.all()]
|
|
34
|
+
return available_findings
|
|
35
|
+
|
|
36
|
+
def remove_unavailable_findings(
|
|
37
|
+
self,
|
|
38
|
+
findings
|
|
39
|
+
):
|
|
40
|
+
"""
|
|
41
|
+
Returns a list of findings that are in the input list but not available for this location classification.
|
|
42
|
+
"""
|
|
43
|
+
from endoreg_db.models import Finding
|
|
44
|
+
for _ in findings:
|
|
45
|
+
assert isinstance(_, Finding)
|
|
46
|
+
available_findings:List['Finding'] = self.get_available_findings()
|
|
47
|
+
available_finding_names = [
|
|
48
|
+
finding.name for finding in available_findings
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
filtered_findings = []
|
|
52
|
+
|
|
53
|
+
for finding in findings:
|
|
54
|
+
if finding.name in available_finding_names:
|
|
55
|
+
filtered_findings.append(finding)
|
|
56
|
+
|
|
57
|
+
return filtered_findings
|
|
58
|
+
|
|
59
|
+
def get_choices(self):
|
|
60
|
+
return self.choices.all()
|
|
61
|
+
|
|
62
|
+
class FindingLocationClassificationChoiceManager(models.Manager):
|
|
63
|
+
def get_by_natural_key(self, name):
|
|
64
|
+
return self.get(name=name)
|
|
65
|
+
|
|
66
|
+
class FindingLocationClassificationChoice(models.Model):
|
|
67
|
+
name = models.CharField(max_length=100, unique=True)
|
|
68
|
+
name_de = models.CharField(max_length=100, blank=True, null=True)
|
|
69
|
+
name_en = models.CharField(max_length=100, blank=True, null=True)
|
|
70
|
+
description = models.TextField(blank=True, null=True)
|
|
71
|
+
description_de = models.TextField(blank=True, null=True)
|
|
72
|
+
description_en = models.TextField(blank=True, null=True)
|
|
73
|
+
|
|
74
|
+
# Foreign key relationships: # migrated to organs
|
|
75
|
+
# organs = models.ManyToManyField('Organ', blank=True, related_name='location_choices')
|
|
76
|
+
|
|
77
|
+
# Optional Descriptors:
|
|
78
|
+
# subcategories_str is a List of strings with names of categorical descriptors
|
|
79
|
+
subcategories = models.JSONField(blank=True, null=True)
|
|
80
|
+
numerical_descriptors = models.JSONField(blank=True, null=True)
|
|
81
|
+
|
|
82
|
+
objects = FindingLocationClassificationChoiceManager()
|
|
83
|
+
|
|
84
|
+
def natural_key(self):
|
|
85
|
+
return (self.name,)
|
|
86
|
+
|
|
87
|
+
def __str__(self):
|
|
88
|
+
return self.name
|
|
89
|
+
|
|
90
|
+
def get_subcategories(self)->dict:
|
|
91
|
+
return self.subcategories
|
|
92
|
+
|
|
93
|
+
def get_numerical_descriptors(self)->dict:
|
|
94
|
+
return self.numerical_descriptors
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
from typing import List
|
|
3
|
+
|
|
4
|
+
class FindingMorphologyClassificationTypeManager(models.Manager):
|
|
5
|
+
def get_by_natural_key(self, name):
|
|
6
|
+
return self.get(name=name)
|
|
7
|
+
|
|
8
|
+
class FindingMorphologyClassificationType(models.Model):
|
|
9
|
+
name = models.CharField(max_length=255, unique=True)
|
|
10
|
+
name_de = models.CharField(max_length=255, blank=True)
|
|
11
|
+
name_en = models.CharField(max_length=255, blank=True)
|
|
12
|
+
description = models.TextField(blank=True)
|
|
13
|
+
|
|
14
|
+
objects = FindingMorphologyClassificationTypeManager()
|
|
15
|
+
|
|
16
|
+
def natural_key(self):
|
|
17
|
+
return (self.name,)
|
|
18
|
+
|
|
19
|
+
def __str__(self):
|
|
20
|
+
return self.name
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def get_required_classifications_for_finding(cls, finding):
|
|
24
|
+
"""
|
|
25
|
+
Returns all required morphology classification types for a given finding.
|
|
26
|
+
"""
|
|
27
|
+
from endoreg_db.models import FindingMorphologyClassificationType
|
|
28
|
+
required_classification_types:List[FindingMorphologyClassificationType] = [
|
|
29
|
+
_ for _ in finding.required_morphology_classification_types.all()
|
|
30
|
+
]
|
|
31
|
+
return required_classification_types
|
|
32
|
+
|
|
33
|
+
class FindingMorphologyClassificationManager(models.Manager):
|
|
34
|
+
def get_by_natural_key(self, name):
|
|
35
|
+
return self.get(name=name)
|
|
36
|
+
|
|
37
|
+
class FindingMorphologyClassification(models.Model):
|
|
38
|
+
name = models.CharField(max_length=255, unique=True)
|
|
39
|
+
name_de = models.CharField(max_length=255, blank=True)
|
|
40
|
+
name_en = models.CharField(max_length=255, blank=True)
|
|
41
|
+
description = models.TextField(blank=True)
|
|
42
|
+
classification_type = models.ForeignKey(FindingMorphologyClassificationType, on_delete=models.CASCADE)
|
|
43
|
+
|
|
44
|
+
objects = FindingMorphologyClassificationManager()
|
|
45
|
+
|
|
46
|
+
def natural_key(self):
|
|
47
|
+
return (self.name,)
|
|
48
|
+
|
|
49
|
+
def __str__(self):
|
|
50
|
+
return self.name
|
|
51
|
+
|
|
52
|
+
def get_choices(self):
|
|
53
|
+
choices: List[FindingMorphologyClassificationChoice] = [_ for _ in self.choices.all()]
|
|
54
|
+
return choices
|
|
55
|
+
|
|
56
|
+
class FindingMorphologyClassificationChoiceManager(models.Manager):
|
|
57
|
+
def get_by_natural_key(self, name):
|
|
58
|
+
return self.get(name=name)
|
|
59
|
+
|
|
60
|
+
class FindingMorphologyClassificationChoice(models.Model):
|
|
61
|
+
name = models.CharField(max_length=255, unique=True)
|
|
62
|
+
name_de = models.CharField(max_length=255, blank=True)
|
|
63
|
+
name_en = models.CharField(max_length=255, blank=True)
|
|
64
|
+
description = models.TextField(blank=True)
|
|
65
|
+
classification = models.ForeignKey(
|
|
66
|
+
FindingMorphologyClassification,
|
|
67
|
+
on_delete=models.CASCADE,
|
|
68
|
+
related_name='choices'
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
subcategories = models.JSONField(
|
|
72
|
+
default = dict
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
numerical_descriptors = models.JSONField(
|
|
76
|
+
default = dict
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
objects = FindingMorphologyClassificationChoiceManager()
|
|
80
|
+
|
|
81
|
+
def natural_key(self):
|
|
82
|
+
return (self.name,)
|
|
83
|
+
|
|
84
|
+
def __str__(self):
|
|
85
|
+
_str = f"{self.name} ({self.classification})"
|
|
86
|
+
return _str
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class FindingTypeManager(models.Manager):
|
|
5
|
+
def get_by_natural_key(self, name):
|
|
6
|
+
return self.get(name=name)
|
|
7
|
+
|
|
8
|
+
class FindingType(models.Model):
|
|
9
|
+
name = models.CharField(max_length=100, unique=True)
|
|
10
|
+
name_de = models.CharField(max_length=100, blank=True, null=True)
|
|
11
|
+
name_en = models.CharField(max_length=100, blank=True, null=True)
|
|
12
|
+
description = models.TextField(blank=True, null=True)
|
|
13
|
+
description_de = models.TextField(blank=True, null=True)
|
|
14
|
+
description_en = models.TextField(blank=True, null=True)
|
|
15
|
+
|
|
16
|
+
objects = FindingTypeManager()
|
|
17
|
+
|
|
18
|
+
def natural_key(self):
|
|
19
|
+
return (self.name,)
|
|
20
|
+
|
|
21
|
+
def __str__(self):
|
|
22
|
+
return self.name
|
|
@@ -8,7 +8,23 @@ class Endoscope(models.Model):
|
|
|
8
8
|
objects = EndoscopeManager()
|
|
9
9
|
|
|
10
10
|
name = models.CharField(max_length=255)
|
|
11
|
+
name_de = models.CharField(max_length=255, blank=True, null=True)
|
|
12
|
+
name_en = models.CharField(max_length=255, blank=True, null=True)
|
|
11
13
|
sn = models.CharField(max_length=255)
|
|
14
|
+
center = models.ForeignKey(
|
|
15
|
+
'Center',
|
|
16
|
+
blank=True,
|
|
17
|
+
null=True,
|
|
18
|
+
on_delete=models.CASCADE,
|
|
19
|
+
related_name='endoscopes'
|
|
20
|
+
)
|
|
21
|
+
endoscope_type = models.ForeignKey(
|
|
22
|
+
'EndoscopeType',
|
|
23
|
+
blank=True,
|
|
24
|
+
null=True,
|
|
25
|
+
on_delete=models.CASCADE,
|
|
26
|
+
related_name='endoscopes'
|
|
27
|
+
)
|
|
12
28
|
|
|
13
29
|
def natural_key(self):
|
|
14
30
|
return (self.name, self.sn)
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
from django.db import models
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
class EndoscopyProcessorManager(models.Manager):
|
|
4
5
|
def get_by_natural_key(self, name):
|
|
5
6
|
return self.get(name=name)
|
|
6
7
|
|
|
8
|
+
|
|
7
9
|
class EndoscopyProcessor(models.Model):
|
|
8
10
|
objects = EndoscopyProcessorManager()
|
|
9
11
|
|
|
12
|
+
centers = models.ManyToManyField(
|
|
13
|
+
"Center",
|
|
14
|
+
blank=True,
|
|
15
|
+
related_name="endoscopy_processors",
|
|
16
|
+
)
|
|
17
|
+
|
|
10
18
|
name = models.CharField(max_length=255)
|
|
11
19
|
image_width = models.IntegerField()
|
|
12
20
|
image_height = models.IntegerField()
|
|
@@ -62,74 +70,78 @@ class EndoscopyProcessor(models.Model):
|
|
|
62
70
|
|
|
63
71
|
def natural_key(self):
|
|
64
72
|
return (self.name,)
|
|
65
|
-
|
|
73
|
+
|
|
74
|
+
@classmethod
|
|
75
|
+
def get_by_name(self, name):
|
|
76
|
+
return self.objects.get(name=name)
|
|
77
|
+
|
|
66
78
|
def __str__(self):
|
|
67
79
|
return self.name
|
|
68
|
-
|
|
80
|
+
|
|
69
81
|
def get_roi_endoscope_image(self):
|
|
70
82
|
return {
|
|
71
83
|
"x": self.endoscope_image_x,
|
|
72
84
|
"y": self.endoscope_image_y,
|
|
73
85
|
"width": self.endoscope_image_width,
|
|
74
|
-
"height": self.endoscope_image_height
|
|
86
|
+
"height": self.endoscope_image_height,
|
|
75
87
|
}
|
|
76
|
-
|
|
88
|
+
|
|
77
89
|
def get_roi_examination_date(self):
|
|
78
90
|
return {
|
|
79
91
|
"x": self.examination_date_x,
|
|
80
92
|
"y": self.examination_date_y,
|
|
81
93
|
"width": self.examination_date_width,
|
|
82
|
-
"height": self.examination_date_height
|
|
94
|
+
"height": self.examination_date_height,
|
|
83
95
|
}
|
|
84
|
-
|
|
96
|
+
|
|
85
97
|
def get_roi_examination_time(self):
|
|
86
98
|
return {
|
|
87
99
|
"x": self.examination_time_x,
|
|
88
100
|
"y": self.examination_time_y,
|
|
89
101
|
"width": self.examination_time_width,
|
|
90
|
-
"height": self.examination_time_height
|
|
102
|
+
"height": self.examination_time_height,
|
|
91
103
|
}
|
|
92
|
-
|
|
104
|
+
|
|
93
105
|
def get_roi_patient_last_name(self):
|
|
94
106
|
return {
|
|
95
107
|
"x": self.patient_last_name_x,
|
|
96
108
|
"y": self.patient_last_name_y,
|
|
97
109
|
"width": self.patient_last_name_width,
|
|
98
|
-
"height": self.patient_last_name_height
|
|
110
|
+
"height": self.patient_last_name_height,
|
|
99
111
|
}
|
|
100
|
-
|
|
112
|
+
|
|
101
113
|
def get_roi_patient_first_name(self):
|
|
102
114
|
return {
|
|
103
115
|
"x": self.patient_first_name_x,
|
|
104
116
|
"y": self.patient_first_name_y,
|
|
105
117
|
"width": self.patient_first_name_width,
|
|
106
|
-
"height": self.patient_first_name_height
|
|
118
|
+
"height": self.patient_first_name_height,
|
|
107
119
|
}
|
|
108
|
-
|
|
120
|
+
|
|
109
121
|
def get_roi_patient_dob(self):
|
|
110
122
|
return {
|
|
111
123
|
"x": self.patient_dob_x,
|
|
112
124
|
"y": self.patient_dob_y,
|
|
113
125
|
"width": self.patient_dob_width,
|
|
114
|
-
"height": self.patient_dob_height
|
|
126
|
+
"height": self.patient_dob_height,
|
|
115
127
|
}
|
|
116
|
-
|
|
128
|
+
|
|
117
129
|
def get_roi_endoscope_type(self):
|
|
118
130
|
return {
|
|
119
131
|
"x": self.endoscope_type_x,
|
|
120
132
|
"y": self.endoscope_type_y,
|
|
121
133
|
"width": self.endoscope_type_width,
|
|
122
|
-
"height": self.endoscope_type_height
|
|
134
|
+
"height": self.endoscope_type_height,
|
|
123
135
|
}
|
|
124
|
-
|
|
136
|
+
|
|
125
137
|
def get_roi_endoscopy_sn(self):
|
|
126
138
|
return {
|
|
127
139
|
"x": self.endoscope_sn_x,
|
|
128
140
|
"y": self.endoscope_sn_y,
|
|
129
141
|
"width": self.endoscope_sn_width,
|
|
130
|
-
"height": self.endoscope_sn_height
|
|
142
|
+
"height": self.endoscope_sn_height,
|
|
131
143
|
}
|
|
132
|
-
|
|
144
|
+
|
|
133
145
|
def get_rois(self):
|
|
134
146
|
return {
|
|
135
147
|
"endoscope_image": self.get_roi_endoscope_image(),
|
|
@@ -139,5 +151,5 @@ class EndoscopyProcessor(models.Model):
|
|
|
139
151
|
"patient_last_name": self.get_roi_patient_last_name(),
|
|
140
152
|
"patient_dob": self.get_roi_patient_dob(),
|
|
141
153
|
"endoscope_type": self.get_roi_endoscope_type(),
|
|
142
|
-
"endoscope_sn": self.get_roi_endoscopy_sn()
|
|
154
|
+
"endoscope_sn": self.get_roi_endoscopy_sn(),
|
|
143
155
|
}
|
endoreg_db/models/label/label.py
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
from django.db import models
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
class LabelTypeManager(models.Manager):
|
|
4
5
|
def get_by_natural_key(self, name):
|
|
5
6
|
return self.get(name=name)
|
|
6
7
|
|
|
8
|
+
|
|
7
9
|
class LabelType(models.Model):
|
|
8
10
|
"""
|
|
9
11
|
A class representing a label type.
|
|
@@ -13,22 +15,28 @@ class LabelType(models.Model):
|
|
|
13
15
|
description (str): A description of the label type.
|
|
14
16
|
|
|
15
17
|
"""
|
|
18
|
+
|
|
16
19
|
name = models.CharField(max_length=255)
|
|
17
20
|
description = models.TextField(blank=True, null=True)
|
|
18
21
|
|
|
19
22
|
objects = LabelTypeManager()
|
|
20
23
|
|
|
21
24
|
def natural_key(self):
|
|
25
|
+
"""Return the natural key of this label type"""
|
|
22
26
|
return (self.name,)
|
|
23
27
|
|
|
24
28
|
def __str__(self):
|
|
25
|
-
return self.name
|
|
29
|
+
return str(self.name)
|
|
26
30
|
|
|
27
31
|
|
|
28
32
|
class LabelManager(models.Manager):
|
|
33
|
+
"""Manager class for handling Label model operations."""
|
|
34
|
+
|
|
29
35
|
def get_by_natural_key(self, name):
|
|
36
|
+
"""Retrieves a Label instance by its natural key (name)."""
|
|
30
37
|
return self.get(name=name)
|
|
31
38
|
|
|
39
|
+
|
|
32
40
|
class Label(models.Model):
|
|
33
41
|
"""
|
|
34
42
|
A class representing a label.
|
|
@@ -39,22 +47,37 @@ class Label(models.Model):
|
|
|
39
47
|
description (str): A description of the label.
|
|
40
48
|
|
|
41
49
|
"""
|
|
50
|
+
|
|
42
51
|
name = models.CharField(max_length=255)
|
|
43
|
-
label_type = models.ForeignKey(
|
|
52
|
+
label_type = models.ForeignKey(
|
|
53
|
+
"LabelType", on_delete=models.CASCADE, related_name="labels"
|
|
54
|
+
)
|
|
44
55
|
description = models.TextField(blank=True, null=True)
|
|
45
56
|
|
|
46
57
|
objects = LabelManager()
|
|
47
58
|
|
|
48
59
|
def natural_key(self):
|
|
60
|
+
"""Return the natural key of this label"""
|
|
49
61
|
return (self.name,)
|
|
50
62
|
|
|
51
63
|
def __str__(self):
|
|
52
|
-
return self.name
|
|
64
|
+
return str(self.name)
|
|
65
|
+
|
|
53
66
|
|
|
54
67
|
class LabelSetManager(models.Manager):
|
|
68
|
+
"""
|
|
69
|
+
Manager class for handling LabelSet model operations.
|
|
70
|
+
Methods
|
|
71
|
+
-------
|
|
72
|
+
get_by_natural_key(name)
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
|
|
55
76
|
def get_by_natural_key(self, name):
|
|
77
|
+
"""Retrieves a LabelSet instance by its natural key (name)."""
|
|
56
78
|
return self.get(name=name)
|
|
57
79
|
|
|
80
|
+
|
|
58
81
|
class LabelSet(models.Model):
|
|
59
82
|
"""
|
|
60
83
|
A class representing a label set.
|
|
@@ -64,21 +87,26 @@ class LabelSet(models.Model):
|
|
|
64
87
|
description (str): A description of the label set.
|
|
65
88
|
|
|
66
89
|
"""
|
|
90
|
+
|
|
67
91
|
name = models.CharField(max_length=255)
|
|
68
92
|
description = models.TextField(blank=True, null=True)
|
|
69
93
|
version = models.IntegerField()
|
|
70
94
|
labels = models.ManyToManyField("Label", related_name="labels")
|
|
71
|
-
|
|
95
|
+
|
|
72
96
|
objects = LabelSetManager()
|
|
73
97
|
|
|
74
98
|
def natural_key(self):
|
|
99
|
+
"""Return the natural key of this label set"""
|
|
75
100
|
return (self.name,)
|
|
76
101
|
|
|
77
102
|
def __str__(self):
|
|
78
|
-
return self.name
|
|
79
|
-
|
|
103
|
+
return str(self.name)
|
|
104
|
+
|
|
80
105
|
def get_labels_in_order(self):
|
|
81
106
|
"""
|
|
82
107
|
Get all labels in this label set as list in the correct order.
|
|
108
|
+
Ordered by string representation (a is first).
|
|
83
109
|
"""
|
|
84
|
-
|
|
110
|
+
labels = list(self.labels.all())
|
|
111
|
+
labels.sort(key=lambda x: x.name)
|
|
112
|
+
return labels
|
|
@@ -63,7 +63,11 @@ class LabValue(models.Model):
|
|
|
63
63
|
warnings.warn("No default distribution set for lab value")
|
|
64
64
|
return None
|
|
65
65
|
|
|
66
|
-
def get_normal_range(self, age=None, gender=None):
|
|
66
|
+
def get_normal_range(self, age:int=None, gender=None):
|
|
67
|
+
from endoreg_db.models import Gender
|
|
68
|
+
assert isinstance(age, int) or age is None
|
|
69
|
+
assert isinstance(gender, Gender) or gender is None
|
|
70
|
+
|
|
67
71
|
age_dependent = self.normal_range_age_dependent
|
|
68
72
|
gender_dependent = self.normal_range_gender_dependent
|
|
69
73
|
special_case = self.normal_range_special_case
|
|
@@ -90,7 +94,7 @@ class LabValue(models.Model):
|
|
|
90
94
|
choices = ["male", "female"]
|
|
91
95
|
gender = choice(choices)
|
|
92
96
|
|
|
93
|
-
default_range_dict = self.default_normal_range.get(gender, {})
|
|
97
|
+
default_range_dict = self.default_normal_range.get(gender.name, {})
|
|
94
98
|
min_value = default_range_dict.get('min', None)
|
|
95
99
|
max_value = default_range_dict.get('max', None)
|
|
96
100
|
|
|
@@ -98,5 +102,10 @@ class LabValue(models.Model):
|
|
|
98
102
|
# get normal range for special case
|
|
99
103
|
warnings.warn("Special case normal range not implemented yet")
|
|
100
104
|
|
|
101
|
-
|
|
105
|
+
normal_range_dict = {
|
|
106
|
+
"min": min_value,
|
|
107
|
+
"max": max_value
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return normal_range_dict
|
|
102
111
|
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
from .base import AbstractLogEntry
|
|
2
2
|
from .network_device import NetworkDeviceLogEntry
|
|
3
3
|
from .log_type import LogType
|
|
4
|
-
from .agl_service import AglServiceLogEntry
|
|
4
|
+
from .agl_service import AglServiceLogEntry
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"AbstractLogEntry",
|
|
8
|
+
"NetworkDeviceLogEntry",
|
|
9
|
+
"LogType",
|
|
10
|
+
"AglServiceLogEntry",
|
|
11
|
+
]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Insert models for Client, Client Type, Client Tag
|
|
2
|
+
|
|
3
|
+
from django.db import models
|
|
4
|
+
|
|
5
|
+
class LxClientTypeManager(models.Manager):
|
|
6
|
+
def get_by_natural_key(self, name):
|
|
7
|
+
return self.get(name=name)
|
|
8
|
+
|
|
9
|
+
#TODO implement base population for client Type
|
|
10
|
+
|
|
11
|
+
class LxClientType(models.Model):
|
|
12
|
+
name = models.CharField(max_length=100, unique=True)
|
|
13
|
+
abbreviation = models.CharField(max_length=10, unique=True) # New field
|
|
14
|
+
description = models.TextField(blank=True)
|
|
15
|
+
objects = LxClientTypeManager()
|
|
16
|
+
|
|
17
|
+
def __str__(self):
|
|
18
|
+
return self.name
|
|
19
|
+
|
|
20
|
+
def natural_key(self):
|
|
21
|
+
return (self.name,)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class LxClientTagManager(models.Manager):
|
|
25
|
+
def get_by_natural_key(self, name):
|
|
26
|
+
return self.get(name=name)
|
|
27
|
+
|
|
28
|
+
#TODO implement base population for client Tag
|
|
29
|
+
|
|
30
|
+
class LxClientTag(models.Model):
|
|
31
|
+
name = models.CharField(max_length=100, unique=True)
|
|
32
|
+
description = models.TextField(blank=True)
|
|
33
|
+
objects = LxClientTagManager()
|
|
34
|
+
|
|
35
|
+
# M2M relationship with LxPermission
|
|
36
|
+
permissions = models.ManyToManyField('LxPermission', blank=True, related_name="allowed_client_tags")
|
|
37
|
+
|
|
38
|
+
def __str__(self):
|
|
39
|
+
return self.name
|
|
40
|
+
|
|
41
|
+
def natural_key(self):
|
|
42
|
+
return (self.name,)
|
|
43
|
+
|
|
44
|
+
class LxClientManager(models.Manager):
|
|
45
|
+
def get_by_natural_key(self, name):
|
|
46
|
+
return self.get(name=name)
|
|
47
|
+
|
|
48
|
+
#TODO implement base population for client
|
|
49
|
+
|
|
50
|
+
class LxClient(models.Model):
|
|
51
|
+
name = models.CharField(max_length=100, unique=True)
|
|
52
|
+
description = models.TextField(blank=True)
|
|
53
|
+
client_type = models.ForeignKey(LxClientType, on_delete=models.CASCADE)
|
|
54
|
+
client_tags = models.ManyToManyField(LxClientTag, blank=True)
|
|
55
|
+
vpn_ip = models.GenericIPAddressField(blank=True, null=True)
|
|
56
|
+
objects = LxClientManager()
|
|
57
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
class LxIdentityTypeManager(models.Manager):
|
|
4
|
+
def get_by_natural_key(self, name):
|
|
5
|
+
return self.get(name=name)
|
|
6
|
+
|
|
7
|
+
#TODO implement base population for identity Type
|
|
8
|
+
## ed25519, rsa, ecdsa, dsa, etc
|
|
9
|
+
|
|
10
|
+
class LxIdentityType(models.Model):
|
|
11
|
+
name = models.CharField(max_length=100, unique=True)
|
|
12
|
+
description = models.TextField(blank=True)
|
|
13
|
+
objects = LxIdentityTypeManager()
|
|
14
|
+
|
|
15
|
+
def __str__(self):
|
|
16
|
+
return self.name
|
|
17
|
+
|
|
18
|
+
def natural_key(self):
|
|
19
|
+
return (self.name,)
|
|
20
|
+
|
|
21
|
+
class LxIdentity(models.Model):
|
|
22
|
+
name = models.CharField(max_length=100, unique=True)
|
|
23
|
+
description = models.TextField(blank=True)
|
|
24
|
+
identity_type = models.ForeignKey(LxIdentityType, on_delete=models.CASCADE)
|
|
25
|
+
objects = models.Manager()
|
|
26
|
+
|
|
27
|
+
# Foreign key to user, nullable
|
|
28
|
+
user = models.ForeignKey('LxUser', on_delete=models.CASCADE, null=True, blank=True)
|
|
29
|
+
|
|
30
|
+
def __str__(self):
|
|
31
|
+
return self.name
|
|
32
|
+
|
|
33
|
+
def natural_key(self):
|
|
34
|
+
return (self.name,)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
class LxPermissionManager(models.Manager):
|
|
4
|
+
def get_by_natural_key(self, name):
|
|
5
|
+
return self.get(name=name)
|
|
6
|
+
|
|
7
|
+
#TODO implement base population for permission
|
|
8
|
+
|
|
9
|
+
class LxPermission(models.Model):
|
|
10
|
+
name = models.CharField(max_length=100, unique=True)
|
|
11
|
+
description = models.TextField(blank=True)
|
|
12
|
+
objects = LxPermissionManager()
|
|
13
|
+
|
|
14
|
+
def __str__(self):
|
|
15
|
+
return self.name
|
|
16
|
+
|
|
17
|
+
def natural_key(self):
|
|
18
|
+
return (self.name,)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
class LxUserManager(models.Manager):
|
|
4
|
+
def get_by_natural_key(self, name):
|
|
5
|
+
return self.get(name=name)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LxUser(models.Model):
|
|
9
|
+
name = models.CharField(max_length=100, unique=True)
|
|
10
|
+
description = models.TextField(blank=True)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# to be extended
|
|
15
|
+
|
|
16
|
+
|
|
@@ -1 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
"""Medication models initialization module."""
|
|
2
|
+
from .medication import Medication, MedicationManager
|
|
3
|
+
from .medication_schedule import MedicationSchedule, MedicationScheduleManager
|
|
4
|
+
from .medication_intake_time import MedicationIntakeTime, MedicationIntakeTimeManager
|
|
5
|
+
from .medication_indication_type import MedicationIndicationType, MedicationIndicationTypeManager
|
|
6
|
+
from .medication_indication import MedicationIndication, MedicationIndicationManager
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"Medication",
|
|
10
|
+
"MedicationManager",
|
|
11
|
+
"MedicationSchedule",
|
|
12
|
+
"MedicationScheduleManager",
|
|
13
|
+
"MedicationIntakeTime",
|
|
14
|
+
"MedicationIntakeTimeManager",
|
|
15
|
+
"MedicationIndicationType",
|
|
16
|
+
"MedicationIndicationTypeManager",
|
|
17
|
+
"MedicationIndication",
|
|
18
|
+
"MedicationIndicationManager"
|
|
19
|
+
]
|