Skip to content

Commit 9472a27

Browse files
committed
Cleanup old ResponseSet model
1 parent 898c632 commit 9472a27

File tree

5 files changed

+28
-365
lines changed

5 files changed

+28
-365
lines changed

lung_cancer_screening/questions/migrations/0020_responseset_user_and_more.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ class Migration(migrations.Migration):
2828
migrations.AlterField(
2929
model_name='responseset',
3030
name='respiratory_conditions',
31-
field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(choices=[('P', 'Pneumonia'), ('E', 'Emphysema'), ('B', 'Bronchitis'), ('T', 'Tuberculosis (TB)'), ('C', 'Chronic obstructive pulmonary disease (COPD)'), ('N', 'No, I have not had any of these respiratory conditions')], max_length=1), blank=True, null=True, size=None, validators=[lung_cancer_screening.questions.models.response_set.validate_singleton_option]),
31+
field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(choices=[('P', 'Pneumonia'), ('E', 'Emphysema'), ('B', 'Bronchitis'), ('T', 'Tuberculosis (TB)'), ('C', 'Chronic obstructive pulmonary disease (COPD)'), ('N', 'No, I have not had any of these respiratory conditions')], max_length=1), blank=True, null=True, size=None, validators=[lung_cancer_screening.questions.models.respiratory_conditions_response.validate_singleton_option]),
3232
),
3333
]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,33 @@
11
from django.db import models
22

33

4+
class BaseQuerySet(models.QuerySet):
5+
def get_or_build(self, **kwargs):
6+
"""
7+
Get an existing object matching the kwargs, or build a new unsaved instance.
8+
Returns a tuple of (object, created) where created is True if a new instance was built.
9+
"""
10+
# Check if any kwargs are unsaved model instances
11+
for key, value in kwargs.items():
12+
if isinstance(value, models.Model) and value.pk is None:
13+
# If we have an unsaved instance, just build a new one
14+
return (self.model(**kwargs), True)
15+
16+
try:
17+
return (self.get(**kwargs), False)
18+
except self.model.DoesNotExist:
19+
return (self.model(**kwargs), True)
20+
21+
422
class BaseModel(models.Model):
523
class Meta:
624
abstract = True
725

826
created_at = models.DateTimeField(auto_now_add=True)
927
updated_at = models.DateTimeField(auto_now=True)
1028

29+
objects = BaseQuerySet.as_manager()
30+
1131
def save(self, *args, **kwargs):
1232
self.full_clean() # Validate before saving
1333
super().save(*args, **kwargs)
Lines changed: 2 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,12 @@
11
from django.db import models
2-
from django.contrib.postgres.fields import ArrayField
32
from django.core.exceptions import ValidationError
4-
from django.core.validators import MaxValueValidator, MinValueValidator
53
from dateutil.relativedelta import relativedelta
64
from django.utils import timezone
7-
from decimal import Decimal
85

9-
from .base import BaseModel
6+
from .base import BaseModel, BaseQuerySet
107
from .user import User
118

12-
class HaveYouEverSmokedValues(models.IntegerChoices):
13-
YES_I_CURRENTLY_SMOKE = 0, 'Yes, I currently smoke'
14-
YES_I_USED_TO_SMOKE_REGULARLY = 1, 'Yes, I used to smoke'
15-
YES_BUT_ONLY_A_FEW_TIMES = 2, 'Yes, but I have smoked fewer than 100 cigarettes in my lifetime'
16-
NO_I_HAVE_NEVER_SMOKED = 3, 'No, I have never smoked'
17-
18-
class SexAtBirthValues(models.TextChoices):
19-
FEMALE = "F", 'Female'
20-
MALE = "M", 'Male'
21-
22-
class GenderValues(models.TextChoices):
23-
FEMALE = "F", 'Female'
24-
MALE = "M", 'Male'
25-
NON_BINARY = "N", 'Non-binary'
26-
PREFER_NOT_TO_SAY = "P", 'Prefer not to say'
27-
GP = "G", 'How I describe myself may not match my GP record'
28-
29-
class EthnicityValues(models.TextChoices):
30-
ASIAN = "A", "Asian or Asian British"
31-
BLACK = "B", "Black, African, Caribbean or Black British"
32-
MIXED = "M", "Mixed or multiple ethnic groups"
33-
WHITE = "W", "White"
34-
OTHER = "O", "Other ethnic group"
35-
PREFER_NOT_TO_SAY = "N", "I'd prefer not to say"
36-
37-
class RespiratoryConditionValues(models.TextChoices):
38-
PNEUMONIA = "P", "Pneumonia"
39-
EMPHYSEMA = "E", "Emphysema"
40-
BRONCHITIS = "B", "Bronchitis"
41-
TUBERCULOSIS = "T", "Tuberculosis (TB)"
42-
COPD = "C", "Chronic obstructive pulmonary disease (COPD)"
43-
NONE = "N", "No, I have not had any of these respiratory conditions"
44-
45-
def validate_singleton_option(value):
46-
if value and "N" in value and len(value) > 1:
47-
raise ValidationError(
48-
"Cannot have singleton value and other values selected",
49-
code="singleton_option",
50-
)
51-
52-
class ResponseSetQuerySet(models.QuerySet):
9+
class ResponseSetQuerySet(BaseQuerySet):
5310
def unsubmitted(self):
5411
return self.filter(submitted_at=None)
5512

@@ -66,78 +23,6 @@ class ResponseSet(BaseModel):
6623
# Attributes
6724
user = models.ForeignKey(User, on_delete=models.CASCADE)
6825

69-
have_you_ever_smoked = models.IntegerField(
70-
choices=HaveYouEverSmokedValues.choices,
71-
null=True,
72-
blank=True
73-
)
74-
date_of_birth = models.DateField(null=True, blank=True)
75-
76-
MAX_HEIGHT_METRIC = 2438
77-
MIN_HEIGHT_METRIC = 1397
78-
MAX_HEIGHT_IMPERIAL = 96
79-
MIN_HEIGHT_IMPERIAL = 55
80-
height_metric = models.PositiveIntegerField(null=True, blank=True, validators=[
81-
MinValueValidator(MIN_HEIGHT_METRIC, message="Height must be between 139.7cm and 243.8 cm"),
82-
MaxValueValidator(MAX_HEIGHT_METRIC, message="Height must be between 139.7cm and 243.8 cm"),
83-
])
84-
height_imperial = models.PositiveIntegerField(null=True, blank=True, validators=[
85-
MinValueValidator(
86-
MIN_HEIGHT_IMPERIAL, message="Height must be between 4 feet 7 inches and 8 feet"),
87-
MaxValueValidator(
88-
MAX_HEIGHT_IMPERIAL, message="Height must be between 4 feet 7 inches and 8 feet"),
89-
])
90-
91-
MIN_WEIGHT_METRIC = 254
92-
MAX_WEIGHT_METRIC = 3175
93-
MAX_WEIGHT_IMPERIAL = 700
94-
MIN_WEIGHT_IMPERIAL = 56
95-
96-
weight_metric = models.PositiveIntegerField(null=True, blank=True, validators=[
97-
MinValueValidator(MIN_WEIGHT_METRIC, message="Weight must be between 25.4kg and 317.5kg"),
98-
MaxValueValidator(MAX_WEIGHT_METRIC, message="Weight must be between 25.4kg and 317.5kg"),
99-
])
100-
weight_imperial = models.PositiveIntegerField(null=True, blank=True, validators=[
101-
MinValueValidator(
102-
MIN_WEIGHT_IMPERIAL, message="Weight must be between 4 stone and 50 stone"),
103-
MaxValueValidator(
104-
MAX_WEIGHT_IMPERIAL, message="Weight must be between 4 stone and 50 stone"),
105-
])
106-
107-
sex_at_birth = models.CharField(
108-
max_length=1,
109-
choices=SexAtBirthValues.choices,
110-
null=True,
111-
blank=True
112-
)
113-
114-
gender = models.CharField(
115-
max_length=1,
116-
choices=GenderValues.choices,
117-
null=True,
118-
blank=True
119-
)
120-
121-
ethnicity = models.CharField(
122-
max_length=1,
123-
choices=EthnicityValues.choices,
124-
null=True,
125-
blank=True
126-
)
127-
128-
129-
respiratory_conditions = ArrayField(
130-
models.CharField(max_length=1, choices=RespiratoryConditionValues.choices),
131-
null=True,
132-
blank=True,
133-
validators=[validate_singleton_option]
134-
)
135-
136-
asbestos_exposure = models.BooleanField(
137-
null=True,
138-
blank=True
139-
)
140-
14126
submitted_at = models.DateTimeField(null=True, blank=True)
14227

14328
class Meta:
@@ -161,30 +46,4 @@ def clean(self):
16146
"Responses have already been submitted for this user"
16247
)
16348

164-
@property
165-
def formatted_height(self):
166-
if self.height_metric:
167-
return f"{Decimal(self.height_metric) / 10}cm"
168-
elif self.height_imperial:
169-
value = Decimal(self.height_imperial)
170-
return f"{value // 12} feet {value % 12} inches"
171-
172-
@property
173-
def formatted_weight(self):
174-
if self.weight_metric:
175-
return f"{Decimal(self.weight_metric) / 10}kg"
176-
elif self.weight_imperial:
177-
value = Decimal(self.weight_imperial)
178-
return f"{value // 14} stone {value % 14} pounds"
179-
180-
@property
181-
def formatted_respiratory_conditions(self):
182-
if not self.respiratory_conditions:
183-
return None
184-
# Get the display values for each code
185-
display_values = [
186-
RespiratoryConditionValues(code).label
187-
for code in self.respiratory_conditions
188-
]
189-
return ", ".join(display_values)
19049

0 commit comments

Comments
 (0)