# coding=utf-8 # from django.core.urlresolvers import reverse from django.urls import reverse from django.db import models #from ck.models import * #from MultiSelect import * # Create your models here. CONTROL_CHOICES = ( ('CR', 'Complete Response'), ('PR', 'Partial Response'), ('SD', 'Stable Disease'), ('PD', 'Progressive Disease'), ) #PRIOR_TX_CHOICES = ( # (10, 'OBS=Observation'), # (20, 'S=Surgery'), # (30, 'CHT=Chemotherapy'), # (40, 'TKI=Target therapy'), # (50, 'RT=Whole brain radiotherapy'), # ) class PriorTx(models.Model): value = models.CharField(max_length=3, primary_key=True) option = models.CharField(max_length=200) def __str__(self): return self.option def instance_fields(instance): """Returns a list of all field names on the instance.""" fields = [] for f in instance._meta.fields: fname = f.name # resolve picklists/choices, with get_xyz_display() function get_choice = 'get_'+fname+'_display' if hasattr( instance, get_choice): value = getattr( instance, get_choice)() else: try : value = getattr(instance, fname) except: value = None # only display fields with values and skip some fields entirely # if f.editable and f.name not in ('id', 'Patient') : # if f.name not in ('id', 'Patient') : # if not f.primary_key: if True: fields.append( { 'verbose_name':f.verbose_name, 'name':f.name, 'value':value, } ) return fields def instance_many_to_many(instance): fields = [] for f in instance._meta.many_to_many: fname = f.name # resolve picklists/choices, with get_xyz_display() function get_choice = 'get_'+fname+'_display' if hasattr( instance, get_choice): value = getattr( instance, get_choice)() else: try : value = getattr(instance, fname) except: value = None if value: value = [x for x in value.all()] fields.append( { 'verbose_name':f.verbose_name, 'name':f.name, 'value':value, } ) return fields class NPatient(models.Model): # Patient = models.ForeignKey('ck.Patient', primary_key=True) Patient = models.OneToOneField('ck.Patient', primary_key=True, on_delete=models.CASCADE) LastModified = models.DateTimeField(auto_now = True) # Name = models.CharField(max_length=200, verbose_name='病患姓名') # Patient Name # ChartID = models.IntegerField(primary_key=True, verbose_name='病歷號碼') # Chart Number # DOB = models.DateField( verbose_name='出生年月日') # Date of Birth # # SEX_CHOICES = ( # (1, 'Male'), # (2, 'Female'), # ) # Sex = models.IntegerField(choices=SEX_CHOICES, verbose_name='性別') # Gender DxDate = models.DateField(null=True, blank=True, verbose_name='診斷日期') # Date of Diagnosis HISTOLOGY_CHOICES = ( (1, 'Adenocarcinoma'), (2, 'Squamous cell carcinoma'), (3, 'Large cell carcinoma'), (4, 'carcinoma, NOS'), (5, 'Adenosquamous carcinoma'), ) Histology = models.IntegerField(choices=HISTOLOGY_CHOICES, null=True, blank=True, verbose_name='組織學型態') # Histology Subtypes BMDate = models.DateField(null=True, blank=True, verbose_name='初次腦轉移日期') # First Date of Diagnosis of Brain Metastases KPS70 = models.BooleanField(null=True, verbose_name='行為狀態量表至少七十分以上') # Karnovsky Performance Status ≥70 ExtraCranialMets = models.BooleanField(null=True, verbose_name='是否有胸腔外轉移病灶') # Presence of Extrathoracic Metastasis DistantControl = models.CharField(max_length=2, choices=CONTROL_CHOICES, null=True, blank=True, verbose_name='三個月內顱外轉移控制狀態') # Control of Extracranial Metastasis within 3 M PrimaryControl = models.BooleanField(null=True,verbose_name='胸腔原發部位控制狀態(Controlled)') # Control of Primary (Thoracic) Disease UpfrontSRS = models.BooleanField(null=True,verbose_name='腦轉移診斷後是否即刻進行電腦刀治療') # Upfront SRS after BM diagnosis PRIOR_TX_CHOICES = ( ('OBS', 'Observation'), ('S', 'Surgery'), ('CHT', 'Chemotherapy'), ('TKI', 'Target therapy'), ('RT', 'Whole brain radiotherapy'), ) # PRIOR_TX_CHOICES = ( # (10, 'OBS=Observation'), # (20, 'S=Surgery'), # (30, 'CHT=Chemotherapy'), # (40, 'TKI=Target therapy'), # (50, 'RT=Whole brain radiotherapy'), # ) # PriorTx = models.CharField(max_length=3, choices=HISTOLOGY_CHOICES, null=True, verbose_name='若非即刻進行電腦刀之治療方式') # Any Tx if SRS is deferred # PriorTx = models.CommaSeparatedIntegerField(max_length=5, choices=PRIOR_TX_CHOICES, null=True, verbose_name='若非即刻進行電腦刀之治療方式') # Any Tx if SRS is deferred # PriorTx = MultiSelectField(max_length=5, choices=PRIOR_TX_CHOICES, null=True, verbose_name='若非即刻進行電腦刀之治療方式') # Any Tx if SRS is deferred priortx = models.ManyToManyField(PriorTx, blank=True, verbose_name='若非即刻進行電腦刀之治療方式') # Any Tx if SRS is deferred PriorWBRT = models.BooleanField(null=True, verbose_name='曾接受全腦放射治療') # History of Prior Whole Brain Radiotherapy WBRTDate = models.DateField( null=True, blank=True, verbose_name='全腦放射治療日期') # Start Date of Prior WBRT AdjuvantWBRT = models.BooleanField(null=True, verbose_name='電腦刀後八週內進行全腦放射治療') # WBRT Within 2 Months after SRS SRSBMDate = models.DateField( null=True, blank=True, verbose_name='進行電腦刀之腦轉移診斷日期') # Diagnosis of Brain Metastsis for SRS BMnumber = models.IntegerField(null=True, blank=True, verbose_name='電腦刀治療腦轉移病灶總數量') # Number of Brain Mets for SRS ########## TKI = models.BooleanField(null=True,verbose_name='同時使用標靶治療') # Concurrent Use of TKI ########## Radionecrosis = models.BooleanField(null=True, verbose_name='放射性壞死') # Presence of Radionecrosis # Pseudoprogression = models.BooleanField(null=True, verbose_name='MRI影像判讀偽惡化') # Pseudoprogression on MRI/MRS/MRP RNDate = models.DateField(null=True, blank=True, verbose_name='診斷放射性壞死日期') # Date of Radionecrosis or Censor NewBM = models.BooleanField(null=True, verbose_name='發生新腦轉移病灶') # Presence of New Brain Metastsis NEW_BM_NUMBER_CHOICES = ( ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('M', '>5'), ) NewBMNumber = models.CharField(max_length=1, choices=NEW_BM_NUMBER_CHOICES, null=True, blank=True, verbose_name='新腦轉移病灶數量') # Number of New Brain Metastasis NewBMDate = models.DateField(null=True, blank=True, verbose_name='診斷新腦轉移病灶日期') # Date of New Brain Metastasis or Censor SALVAGE_TX_CHOICES = ( (0, 'Supportive care'), (1, 'Chemotherapy'), (2, 'Target therapy'), (3, 'WBRT'), (4, 'SRS'), (5, 'Surgery'), ) SalvageTx = models.IntegerField(choices=SALVAGE_TX_CHOICES, null=True, blank=True, verbose_name='新腦轉移病灶治療方法') # Salvage Treatment Death = models.BooleanField(null=True, verbose_name='發生死亡事件') # Death NeuroDeath = models.BooleanField(null=True, verbose_name='因腦轉移導致死亡') # Neurogenic Death Due to Brain Metastasis SurviveDate = models.DateField(null=True, blank=True, verbose_name='存活日期') # Date of Death or Censor DistantProgression = models.BooleanField(null=True, verbose_name='顱外病灶惡化') # Progression of Extracranial Disease DistantDate = models.DateField(null=True, blank=True, verbose_name='顱外病灶惡化日期') # Date of Extracranial Progression or Censor PoorKPS = models.BooleanField(null=True, verbose_name='行為狀態惡化致生活無法自理') # Progression of Extracranial Disease DependentDate = models.DateField(null=True, blank=True, verbose_name='生活開始無法自理日期') # Date of KPS < 70 or Censor ########## EGFR = models.CharField(max_length=200, blank=True, null=True, verbose_name='EGFR Mutation Status') ALK = models.CharField(max_length=200, blank=True, null=True, verbose_name='EML4-ALK Rearrangement') KRAS = models.CharField(max_length=200, blank=True, null=True, verbose_name='K-RAS Mutation Status') BRAF = models.CharField(max_length=200, blank=True, null=True, verbose_name='BRAF Mutation Status') HER2 = models.CharField(max_length=200, blank=True, null=True, verbose_name='HER2 Mutation Status') ThoracicMets = models.BooleanField(null=True, verbose_name='是否有胸腔轉移病灶') # Presence of intrathoracic Metastasis SalvageWBRT = models.BooleanField(null=True, verbose_name='是否接受救援全腦放射治療') # Salvage WBRT after SRS SalvageRTDate = models.DateField(null=True, blank=True, verbose_name='救援全腦放射治療日期') # Date of salvage WBRT SRSDate = models.DateField(null=True, blank=True, verbose_name='執行第一次SRS日期') # Date of first SRS treatment OverallResponse = models.CharField(max_length=2, choices=CONTROL_CHOICES, null=True, blank=True, verbose_name='RECIST整體最佳反應') # Combined best response according to RECIST LocalProgression = models.BooleanField(null=True, verbose_name='RECIST整體局部病灶惡化') # Combined progression according to RECIST LocalDate = models.DateField(null=True, blank=True, verbose_name='RECIST局部病灶惡化日期') # Date of Local Progression PseudoPD = models.BooleanField(null=True, verbose_name='偽惡化') # Pseudoprogression ClinicalProgression = models.BooleanField(null=True, verbose_name='臨床評估局部復發') # Clinical local control RecurDate = models.DateField(null=True, blank=True, verbose_name='臨床評估局部復發日期') # Date of clinical local progression LateSE = models.IntegerField(null=True, blank=True, verbose_name='SRS副作用嚴重程度') # Grading of Late Toxicity def Physician(self): p = None for t in self.Patient.treatment_set.all(): if t.surgeon: return { 'dept': 'surg', 'name': t.surgeon, } else: p = t.oncologist return { 'dept': 'onc', 'name': p, } def get_absolute_url(self): # return reverse('patient_update', kwargs={'pk': self.Patient.id}) return reverse('patient_update', args=[self.Patient.id]) def meta(self): return self._meta def fields(self): return instance_fields(self) def many_to_many(self): return instance_many_to_many(self) class NTarget(models.Model): # Lesion = models.ForeignKey('ck.Lesion', primary_key=True) Lesion = models.OneToOneField('ck.Lesion', primary_key=True, on_delete=models.CASCADE) LastModified = models.DateTimeField(auto_now = True) # TargetID = models.IntegerField(primary_key=True, verbose_name='電腦刀腦轉移病灶編號') # ID of Brain Mets Target for SRS RECIST = models.BooleanField(null=True, blank=True, verbose_name='是否為RECIST可測量病灶') # RECIST Measurable Lesion BMdiameter = models.FloatField( null=True, blank=True, verbose_name='病灶最大直徑(mm)') # Diameter of Brain Metastasis # BMvolume = models.FloatField( verbose_name='病灶體積(mL)') # Volume of Brain Metatasis # SRSdose = models.IntegerField( verbose_name='處方劑量(cGy)') # Prescribe SRS Dose # Fraction = models.IntegerField( verbose_name='治療次數') # Number of SRS fraction # Isodose = models.IntegerField( verbose_name='百分等劑量線(%)') # Prescribed Isodose Line PTV = models.BooleanField(null=True,verbose_name='是否外加PTV邊界') # Additional PTV to Brain Metastasis # MinDose = models.FloatField( verbose_name='百分之九九病灶體積接受劑量(cGy)') # Actual Dose Covering 99% of Target # MaxDose = models.FloatField( verbose_name='病灶最高劑量(cGy)') # Maximal Dose to Target ########## # SRSDate = models.DateField(verbose_name='電腦刀治療日期') # Treatment Date of SRS TargetResponse = models.CharField(max_length=2, choices=CONTROL_CHOICES, null=True, blank=True, verbose_name='RECIST最佳反應') # Best Response of Target TargetControl = models.BooleanField(null=True, verbose_name='電腦刀治療病灶惡化(RECIST)') # RECIST Progression of SRS Target TargetControlDate = models.DateField(null=True, blank=True, verbose_name='電腦刀治療病灶惡化日期') # Date of SRS Target Progression or Censor Pseudoprogression = models.BooleanField(null=True, verbose_name='MRI影像判讀偽惡化') # Pseudoprogression on MRI/MRS/MRP def get_absolute_url(self): return reverse('target_update', args=[self.Lesion.id]) def fields(self): return instance_fields(self)