class EpiduralInsertion(models.EpisodeSubrecord): _is_singleton = True insertion_date_time = fields.DateTimeField( null=True, # default=timezone.now, (causes an Opal APIerror if uncommented) help_text="Date and time of the epidural insertion or epidural insertion attempt", ) #needs to be the current user performed_by = fields.TextField( null=True, blank=True, ) #pick from list of anaesthetist users supervised_by = fields.TextField( null=True, blank=True, ) procedure = ForeignKeyOrFreeText( ProcedureType, help_text="Free text clinical record of the intervention" ) # TODO should ideally be SNOMEDized indication = ForeignKeyOrFreeText( Indication, help_text="Description of the indication", )
class LabTest(EpisodeSubrecord): _sort = 'date_ordered' _icon = 'fa fa-crosshairs' _advanced_searchable = False test = models.CharField(max_length=255) date_ordered = models.DateField(null=True, blank=True) details = models.CharField(max_length=255, blank=True) result = models.CharField(max_length=255, blank=True) significant_organism = models.NullBooleanField(default=False) organism_details = ForeignKeyOrFreeText(Organism_details) antimicrobials_susceptible = ForeignKeyOrFreeText( Antimicrobial_susceptability, related_name='susceptible') antimicrobials_intermediate = ForeignKeyOrFreeText( Antimicrobial_susceptability, related_name='intermediate') antimicrobials_resistant = ForeignKeyOrFreeText( Antimicrobial_susceptability, related_name='resistant') retrieved = models.NullBooleanField(default=False) date_retrieved = models.DateField(null=True, blank=True) sweep_biobanked = models.NullBooleanField(default=False) organism_biobanked = models.NullBooleanField(default=False) freezer_box_number = models.CharField(max_length=200, blank=True, null=True) esbl = models.NullBooleanField(default=False) carbapenemase = models.NullBooleanField(default=False)
class DischargeStep(models.EpisodeSubrecord): _angular_service = 'RequestReceive' discharge_type = ForeignKeyOrFreeText(DischargeType) requested_timestamp = fields.DateTimeField(null=True, blank=True) received_timestamp = fields.DateTimeField(null=True, blank=True) requested = fields.NullBooleanField() transport_type = ForeignKeyOrFreeText(TransportType) destination_type = ForeignKeyOrFreeText(DestinationType) reviewed = fields.NullBooleanField() reviewed_timestamp = fields.DateTimeField(null=True, blank=True)
class Management(omodels.EpisodeSubrecord): _is_singleton = True _icon = 'fa fa-list-ol' follow_up = ForeignKeyOrFreeText(Management_follow_up) follow_up_clinic = ForeignKeyOrFreeText(Management_clinics) date_of_appointment = models.DateField(null=True, blank=True) advice = models.CharField(max_length=255, blank=True, null=True) results_actioned = models.CharField(max_length=255, blank=True, null=True) def __unicode__(self): return u'Management: {0}'.format(self.id)
class Travel(EpisodeSubrecord): _icon = 'fa fa-plane' destination = ForeignKeyOrFreeText(omodels.Destination) dates = models.CharField(max_length=255, blank=True) reason_for_travel = ForeignKeyOrFreeText(omodels.Travel_reason) did_not_travel = models.NullBooleanField(default=False) specific_exposures = models.CharField(max_length=255, blank=True) malaria_prophylaxis = models.NullBooleanField(default=False) malaria_drug = ForeignKeyOrFreeText(omodels.Antimicrobial) malaria_compliance = models.CharField(max_length=200, blank=True, null=True)
class Treatment(EpisodeSubrecord): _sort = 'start_date' _icon = 'fa fa-flask' _modal = 'lg' drug = ForeignKeyOrFreeText(Drug) dose = models.CharField(max_length=255, blank=True) route = ForeignKeyOrFreeText(Drugroute) start_date = models.DateField(null=True, blank=True) end_date = models.DateField(null=True, blank=True) frequency = ForeignKeyOrFreeText(Drugfreq) class Meta: abstract = True
class Imaging(EpisodeSubrecord): _icon = 'fa fa-eye' date = models.DateField(blank=True, null=True) imaging_type = ForeignKeyOrFreeText(ImagingTypes) site = models.CharField(max_length=200, blank=True, null=True) details = models.TextField(blank=True, null=True)
class PatientConsultation(EpisodeSubrecord): _sort = 'when' _icon = 'fa fa-comments' _list_limit = 3 _angular_service = 'PatientConsultationRecord' class Meta: abstract = True verbose_name = "Patient Consultation" when = models.DateTimeField(null=True, blank=True) initials = models.CharField( max_length=255, blank=True, help_text="The initials of the user who gave the consult." ) reason_for_interaction = ForeignKeyOrFreeText( PatientConsultationReasonForInteraction ) discussion = models.TextField(blank=True) def set_when(self, incoming_value, user, *args, **kwargs): if incoming_value: self.when = serialization.deserialize_datetime(incoming_value) else: self.when = timezone.make_aware(datetime.datetime.now())
class SpecialistReview(models.EpisodeSubrecord): _angular_service = 'RequestReceive' specialist_type = ForeignKeyOrFreeText(SpecialistType) requested_timestamp = fields.DateTimeField(null=True, blank=True) received_timestamp = fields.DateTimeField(null=True, blank=True) requested = fields.NullBooleanField() received = fields.NullBooleanField()
class PresentingComplaint(EpisodeSubrecord): _title = 'Presenting Complaint' _icon = 'fa fa-stethoscope' symptom = ForeignKeyOrFreeText(omodels.Symptom) symptoms = models.ManyToManyField(omodels.Symptom, related_name="presenting_complaints") duration = models.CharField(max_length=255, blank=True, null=True) details = models.TextField(blank=True, null=True) def set_symptom(self, *args, **kwargs): # ignore symptom for the time being pass def to_dict(self, user): field_names = self.__class__._get_fieldnames_to_serialize() result = { i: getattr(self, i) for i in field_names if not i == "symptoms" } result["symptoms"] = list(self.symptoms.values_list("name", flat=True)) return result @classmethod def _get_fieldnames_to_serialize(cls): field_names = super(PresentingComplaint, cls)._get_fieldnames_to_serialize() removed_fields = {u'symptom_fk_id', 'symptom_ft', 'symptom'} field_names = [i for i in field_names if i not in removed_fields] return field_names
class EmergencyDepartmentTriage(models.EpisodeSubrecord): _is_singleton = True reason = fields.TextField(blank=True, null=True, verbose_name="Reason For Attendance") mts_score = ForeignKeyOrFreeText(ManchesterTriageScore, verbose_name="Manchester Triage Score")
class Demographics(PatientSubrecord): _is_singleton = True _icon = 'fa fa-user' hospital_number = models.CharField( max_length=255, blank=True, help_text="The unique identifier for this patient at the hospital." ) nhs_number = models.CharField( max_length=255, blank=True, null=True, verbose_name="NHS Number" ) surname = models.CharField(max_length=255, blank=True) first_name = models.CharField(max_length=255, blank=True) middle_name = models.CharField(max_length=255, blank=True, null=True) title = ForeignKeyOrFreeText(Title) date_of_birth = models.DateField( null=True, blank=True, verbose_name="Date of Birth" ) marital_status = ForeignKeyOrFreeText(MaritalStatus) religion = models.CharField(max_length=255, blank=True, null=True) date_of_death = models.DateField( null=True, blank=True, verbose_name="Date of Death" ) post_code = models.CharField(max_length=20, blank=True, null=True) gp_practice_code = models.CharField( max_length=20, blank=True, null=True, verbose_name="GP Practice Code" ) birth_place = ForeignKeyOrFreeText(Destination, verbose_name="Country of Birth") ethnicity = ForeignKeyOrFreeText(Ethnicity) death_indicator = models.BooleanField( default=False, help_text="This field will be True if the patient is deceased." ) sex = ForeignKeyOrFreeText(Gender) @property def name(self): return '{0} {1}'.format(self.first_name, self.surname) class Meta: abstract = True verbose_name_plural = "Demographics"
class Imaging(models.EpisodeSubrecord): _angular_service = 'RequestReceive' _icon = "fa fa-picture-o" test_type = ForeignKeyOrFreeText(ImagingTestType) requested_timestamp = fields.DateTimeField(null=True, blank=True) reviewed_timestamp = fields.DateTimeField(null=True, blank=True) requested = fields.NullBooleanField() reviewed = fields.NullBooleanField()
class Line(EpisodeSubrecord): _sort = 'insertion_datetime' _icon = 'fa fa-bolt' line_type = ForeignKeyOrFreeText(omodels.Line_type) site = ForeignKeyOrFreeText(omodels.Line_site) insertion_datetime = models.DateTimeField(blank=True, null=True) inserted_by = models.CharField(max_length=255, blank=True, null=True) external_length = models.CharField(max_length=255, blank=True, null=True) removal_datetime = models.DateTimeField(blank=True, null=True) complications = ForeignKeyOrFreeText(omodels.Line_complication) removal_reason = ForeignKeyOrFreeText(omodels.Line_removal_reason) special_instructions = models.TextField() button_hole = models.NullBooleanField() tunnelled_or_temp = models.CharField(max_length=200, blank=True, null=True) fistula = models.NullBooleanField(blank=True, null=True) graft = models.NullBooleanField(blank=True, null=True)
class Demographics(PatientSubrecord, ExternallySourcedModel): _is_singleton = True _icon = 'fa fa-user' hospital_number = models.CharField(max_length=255, blank=True) nhs_number = models.CharField(max_length=255, blank=True, null=True) surname = models.CharField(max_length=255, blank=True) first_name = models.CharField(max_length=255, blank=True) middle_name = models.CharField(max_length=255, blank=True, null=True) title = ForeignKeyOrFreeText(omodels.Title) date_of_birth = models.DateField(null=True, blank=True) marital_status = ForeignKeyOrFreeText(omodels.MaritalStatus) religion = models.CharField(max_length=255, blank=True, null=True) date_of_death = models.DateField(null=True, blank=True) post_code = models.CharField(max_length=20, blank=True, null=True) gp_practice_code = models.CharField(max_length=20, blank=True, null=True) birth_place = ForeignKeyOrFreeText(omodels.Destination) ethnicity = ForeignKeyOrFreeText(omodels.Ethnicity) death_indicator = models.BooleanField(default=False) # not strictly correct, but it will be updated when opal core models # are updated sex = ForeignKeyOrFreeText(omodels.Gender) pid_fields = ( 'hospital_number', 'nhs_number', 'surname', 'first_name', 'middle_name', 'post_code', ) class Meta: verbose_name_plural = "Demographics" @classmethod def get_form_template(cls, patient_list=None, episode_type=None): if settings.GLOSS_ENABLED: return super(Demographics, cls).get_form_template(patient_list=None, episode_type=None) else: return "forms/demographics_form_pre_gloss.html"
class MicrobiologyTest(EpisodeSubrecord): _title = 'Investigations' _sort = 'date_ordered' _icon = 'fa fa-crosshairs' _modal = 'lg' test = models.CharField(max_length=255) alert_investigation = models.BooleanField(default=False) date_ordered = models.DateField(null=True, blank=True) details = models.CharField(max_length=255, blank=True) microscopy = models.CharField(max_length=255, blank=True) organism = models.CharField(max_length=255, blank=True) sensitive_antibiotics = models.CharField(max_length=255, blank=True) resistant_antibiotics = models.CharField(max_length=255, blank=True) result = models.CharField(max_length=255, blank=True) igm = models.CharField(max_length=20, blank=True) igg = models.CharField(max_length=20, blank=True) vca_igm = models.CharField(max_length=20, blank=True) vca_igg = models.CharField(max_length=20, blank=True) ebna_igg = models.CharField(max_length=20, blank=True) hbsag = models.CharField(max_length=20, blank=True) anti_hbs = models.CharField(max_length=20, blank=True) anti_hbcore_igm = models.CharField(max_length=20, blank=True) anti_hbcore_igg = models.CharField(max_length=20, blank=True) rpr = models.CharField(max_length=20, blank=True) tppa = models.CharField(max_length=20, blank=True) viral_load = models.CharField(max_length=20, blank=True) parasitaemia = models.CharField(max_length=20, blank=True) hsv = models.CharField(max_length=20, blank=True) vzv = models.CharField(max_length=20, blank=True) syphilis = models.CharField(max_length=20, blank=True) c_difficile_antigen = models.CharField(max_length=20, blank=True) c_difficile_toxin = models.CharField(max_length=20, blank=True) species = models.CharField(max_length=20, blank=True) hsv_1 = models.CharField(max_length=20, blank=True) hsv_2 = models.CharField(max_length=20, blank=True) enterovirus = models.CharField(max_length=20, blank=True) cmv = models.CharField(max_length=20, blank=True) ebv = models.CharField(max_length=20, blank=True) influenza_a = models.CharField(max_length=20, blank=True) influenza_b = models.CharField(max_length=20, blank=True) parainfluenza = models.CharField(max_length=20, blank=True) metapneumovirus = models.CharField(max_length=20, blank=True) rsv = models.CharField(max_length=20, blank=True) adenovirus = models.CharField(max_length=20, blank=True) norovirus = models.CharField(max_length=20, blank=True) rotavirus = models.CharField(max_length=20, blank=True) giardia = models.CharField(max_length=20, blank=True) entamoeba_histolytica = models.CharField(max_length=20, blank=True) cryptosporidium = models.CharField(max_length=20, blank=True) hiv_declined = ForeignKeyOrFreeText(Hiv_no) spotted_fever_igm = models.CharField(max_length=20, blank=True) spotted_fever_igg = models.CharField(max_length=20, blank=True) typhus_group_igm = models.CharField(max_length=20, blank=True) typhus_group_igg = models.CharField(max_length=20, blank=True) scrub_typhus_igm = models.CharField(max_length=20, blank=True) scrub_typhus_igg = models.CharField(max_length=20, blank=True)
class LabTest(models.EpisodeSubrecord): _angular_service = 'RequestReceive' _title = "Investigation" _icon = "fa fa-flask" test_type = ForeignKeyOrFreeText(LabTestType) requested_timestamp = fields.DateTimeField(null=True, blank=True) reviewed_timestamp = fields.DateTimeField(null=True, blank=True) requested = fields.NullBooleanField() reviewed = fields.NullBooleanField()
class Allergies(PatientSubrecord): _icon = 'fa fa-warning' drug = ForeignKeyOrFreeText(Drug) provisional = models.BooleanField(default=False) details = models.CharField(max_length=255, blank=True) class Meta: abstract = True
class Location(EpisodeSubrecord): _is_singleton = True _icon = 'fa fa-map-marker' category = ForeignKeyOrFreeText(LocationCategory) provenance = ForeignKeyOrFreeText(Provenance) hospital = ForeignKeyOrFreeText(omodels.Hospital) ward = ForeignKeyOrFreeText(omodels.Ward) bed = models.CharField(max_length=255, blank=True) def __unicode__(self): try: demographics = self.episode.patient.demographics_set.get() return u'Location for {0}({1}) {2} {3} {4} {5}'.format( demographics.name, demographics.hospital_number, self.category, self.hospital, self.ward, self.bed) except: return 'demographics'
class SecondaryDiagnosis(EpisodeSubrecord): """ This is a confirmed diagnosis at discharge time. """ _title = 'Secondary Diagnosis' condition = ForeignKeyOrFreeText(omodels.Condition) co_primary = models.NullBooleanField(default=False) class Meta: verbose_name_plural = "Secondary diagnoses"
class HaemInformation(PatientSubrecord): _icon = 'fa fa-info-circle' _title = 'Haematology Background Information' patient_type = ForeignKeyOrFreeText(HaemInformationType, verbose_name="Type") date_of_transplant = models.DateField(blank=True, null=True) neutropenia_onset = models.DateField(blank=True, null=True) type_of_transplant = ForeignKeyOrFreeText(HaemTransplantType, verbose_name="Transplant Type") type_of_chemotherapy = ForeignKeyOrFreeText( HaemChemotherapyType, verbose_name="Chemotherapy Type") date_of_chemotherapy = models.DateField(blank=True, null=True) count_recovery = models.DateField(blank=True, null=True) details = models.TextField(blank=True, null=True) @property def icon(self): return self._icon
class ClinicalFindings(omodels.EpisodeSubrecord): _title = 'Clinical Findings' _icon = 'fa fa-stethoscope' lymphadenopathy = models.CharField(max_length=20, blank=True, null=True) lymphadenopathy_details = models.CharField(max_length=255, blank=True, null=True) jaundice = models.CharField(max_length=20, blank=True) dehydrated = models.CharField(max_length=20, blank=True) rash = models.CharField(max_length=20, blank=True) rash_type = ForeignKeyOrFreeText(Findings_rash_type) rash_distribution = ForeignKeyOrFreeText(Findings_rash_distribution) cardiovascular = models.CharField(max_length=255, blank=True, null=True) respiratory = models.CharField(max_length=255, blank=True, null=True) abdominal = models.CharField(max_length=255, blank=True, null=True) oropharnyx = models.CharField(max_length=255, blank=True, null=True) neurological = models.CharField(max_length=255, blank=True, null=True) other_findings = models.CharField(max_length=255, blank=True, null=True)
class Treatment(EpisodeSubrecord): _sort = 'start_date' _icon = 'fa fa-flask' HELP_START = "The date on which the patient began receiving this \ treatment." drug = ForeignKeyOrFreeText(Drug) dose = models.CharField(max_length=255, blank=True) route = ForeignKeyOrFreeText(Drugroute) start_date = models.DateField( null=True, blank=True, help_text=HELP_START ) end_date = models.DateField(null=True, blank=True) frequency = ForeignKeyOrFreeText(Drugfreq) class Meta: abstract = True
class PastMedicalHistory(EpisodeSubrecord): _title = 'PMH' _sort = 'year' _icon = 'fa fa-history' condition = ForeignKeyOrFreeText(omodels.Condition) year = models.CharField(max_length=200, blank=True) details = models.CharField(max_length=255, blank=True) class Meta: verbose_name_plural = "Past medical histories"
class PastMedicalHistory(EpisodeSubrecord): _title = 'PMH' _sort = 'year' _icon = 'fa fa-history' condition = ForeignKeyOrFreeText(Condition) year = models.CharField(max_length=4, blank=True) details = models.CharField(max_length=255, blank=True) class Meta: abstract = True
class OPATReview(EpisodeSubrecord): _sort = 'datetime' _title = 'OPAT Review' _icon = 'fa fa-comments' _list_limit = 1 _modal = 'lg' _angular_service = 'OPATReview' datetime = models.DateTimeField(null=True, blank=True) initials = models.CharField(max_length=255, blank=True) rv_type = ForeignKeyOrFreeText(Opat_rvt) discussion = models.TextField(blank=True, null=True) opat_plan = models.TextField(blank=True) next_review = models.DateField(blank=True, null=True) dressing_changed = models.NullBooleanField(default=False) bung_changed = models.NullBooleanField(default=False) medication_administered = models.TextField(blank=True, null=True) adverse_events = ForeignKeyOrFreeText(omodels.Antimicrobial_adverse_event) class Meta: verbose_name = "OPAT review"
class LabSpecimin(EpisodeSubrecord): _advanced_searchable = False class Meta: verbose_name = "Lab specimen appearance" _title = 'Lab Specimen' _sort = 'date_collected' _icon = 'fa fa-flask' specimin_type = ForeignKeyOrFreeText(Specimin) date_collected = models.DateField(blank=True, null=True) volume = models.CharField(max_length=200, blank=True, null=True) appearance = ForeignKeyOrFreeText(Specimin_appearance) epithelial_cell = models.CharField(max_length=200, blank=True, null=True) white_blood_cells = models.CharField(max_length=200, blank=True, null=True) date_tested = models.DateField(blank=True, null=True) external_id = models.CharField(max_length=200, blank=True, null=True) biobanking = models.NullBooleanField(default=False) biobanking_box = models.CharField(max_length=200, blank=True, null=True) date_biobanked = models.DateField(blank=True, null=True) volume_biobanked = models.CharField(max_length=200, blank=True, null=True)
class PrimaryDiagnosis(EpisodeSubrecord): """ This is the confirmed primary diagnosisa """ _is_singleton = True _title = 'Primary Diagnosis' _icon = 'fa fa-eye' condition = ForeignKeyOrFreeText(PrimaryDiagnosisCondition) confirmed = models.BooleanField(default=False) class Meta: verbose_name_plural = "Primary diagnoses"
class NeuraxialDrugs(models.EpisodeSubrecord): _is_singleton = True spinal_opiate = ForeignKeyOrFreeText( SpinalOpiate, ) spinal_opiate_dose = fields.PositiveIntegerField( null=True, blank=True, ) local_anaesthetic_spinal = ForeignKeyOrFreeText( SpinalLocal, ) spinal_local_anaesthetic_volume = fields.PositiveIntegerField( null=True, blank=True, ) epidural_opiate = ForeignKeyOrFreeText( EpiduralOpiate, ) epidural_opiate_dose = fields.PositiveIntegerField( null=True, blank=True, ) local_anaesthetic_epidural = ForeignKeyOrFreeText( EpiduralLocal, ) epidural_local_anaesthetic_volume = fields.PositiveIntegerField( null=True, blank=True, )
class ReferralRoute(EpisodeSubrecord): _icon = 'fa fa-level-up' _is_singleton = True class Meta: abstract = True verbose_name = 'Referral Route' internal = models.NullBooleanField() # e.g. GP, the title or institution of the person who referred the patient referral_organisation = ForeignKeyOrFreeText(ReferralOrganisation) # the name of the person who referred the patient, e.g. the GPs name referral_name = models.CharField(max_length=255, blank=True) # date_of_referral date_of_referral = models.DateField(null=True, blank=True) # an individual can be from multiple teams referral_team = ForeignKeyOrFreeText(Speciality) referral_type = ForeignKeyOrFreeText(ReferralType)
def test_get_default_when_callable(self): field = ForeignKeyOrFreeText(test_models.Demographics, default=lambda: 'Nope') self.assertEqual('Nope', field.get_default())
def test_get_raises(self): field = ForeignKeyOrFreeText(test_models.Hat) result = field.__get__(self, ForeignKeyOrFreeText) self.assertEqual(result, 'Unknown Lookuplist Entry')