How to efficiently structure conversion logic between model pairs in Django?
I'm working on a Django app where I need to handle conversions between pairs of models with different units of measurement. These models are like tasks which the user needs to complete, and converting units between two tasks attempts to map the effort of the first task to the second, measured in units. My current approach uses a mapping of model pairs (around 30 possible combinations) and applies one of several calculations to a value associated with the from_model based on the pair and the associated unit. I've been given a predefined list of mappings and calculations on the various units of measurement each task has.
Context:
For example, here are two tasks:
Task A: Writing 1 page by hand using a pencil (this contains a value and unit of measurement).
Task B: Typing pages using a computer (this does not contain a value, but does contain the unit of measurement)
A conversion from Model A to Model B would need to take the value (e.g., 1 page) and return an equivalent in terms of effort (e.g., typing 3 pages might be considered equivalent to handwriting 1 page).
Here's my current implementation:
from django.test import TestCase
from app.myapp.models import MyModel
def convert_units(value, from_model, to_model, unit, conversion_map):
try:
conversion_function = conversion_map[(from_model, to_model)][unit]
return conversion_function(value)
except KeyError:
return None
class ConversionTest(TestCase):
def setUp(self):
self.model_a = MyModel.objects.create(name='writing_by_hand')
self.model_b = MyModel.objects.create(name='typing')
self.conversion_map = {
('writing_by_hand', 'typing'): {
'pages': lambda x: x * 3
},
}
def test_convert_units(self):
value = 1
model_a_to_model_b = convert_units(value, self.model_a.name, self.model_b.name, 'pages', self.conversion_map)
self.assertEqual(model_a_to_model_b, value * 3)
self.assertIsNotNone(model_a_to_model_b)
Is there a more efficient or maintainable way to structure this conversion logic? The actual application has a few dozen pairs, and 2-5 units of measurement. Each pair may have more than one unit of measurement.