By field(enum)
" do you mean you are using the choices option on a field?
A simple set of choices works out reasonably well for small lists of conversions. It allows you to make simplifying assumptions that helps your users (and you) get something that works.
Creating a formal model for units should only be done if you have (a) a LOT of units involved, (b) your need to extend it, AND (c) there's some rational expectation that the DB lookups will be of some value.
Units don't change all that often. There seems little reason to use the database for this. It seems a lot simpler to hard-code the list of choices.
Choices
You can, for example, use something like this to keep track of conversions.
UNIT_CHOICES = ( ('m', 'meters'), ('f', 'feet' ), ('i', 'inches'), ('pt', 'points') )
unit_conversions = {
('m','f'): 3.xyz,
('m','i'): 39.xyz,
('m','pt'): 29.xyz*72,
('f','m'): 1/3.xyz,
('f','i'): 12.0,
('f','pt'): 12.0*72,
etc.
}
Given this mapping, you can get a conversion factor in your conversion method
function, do the math, and return the converted unit.
class WithUnit( Model ):
...
def toUnit( self, someUnit ):
if someUnit == self.unit: return self.value
elif (someUnit,self.unit) in unit_conversions:
return self.value * unit_conversions[(someUnit,self.unit)]
else:
raise Exception( "Can't convert" )
Model.
If you want to create a formal model for units, you have to carry around the kind of dimension (length, volume, mass, weight/force, pressure, temperature, etc.) and the various unit conversion factors. This works for everything but temperature, where you have a constant term in addition to a factor.
You have to pick a "baseline" set of units (e.g., MKS) and carry all the multipliers among the various units.
You also have to choose how many of the Imperial units to load into your table (fluid ounces, teaspoons, tablespoons, cups, pints, quarts, etc.)