"Quantity Field for Django using pint library for automated unit conversions"
Project description
Django Quantity Field
A Small django field extension allowing you to store quantities in certain units and perform conversions easily. Uses pint behind the scenes. Also contains a form field class and form widget that allows a user to choose alternative units to input data. The cleaned_data will output the value in the base_units defined for the field, eg: you specify you want to store a value in grams but will allow users to input either grams or ounces.
Compatibility
Requires django >= 2.2, and python 3.6/3.7/3.8/3.9
Installation
pip install django-pint
Simple Example
Best way to illustrate is with an example
# app/models.py
from django.db import models
from quantityfield.fields import QuantityField
class HayBale(models.Model):
weight = QuantityField('tonne')
Quantities are stored as float (Django FloatField) and retrieved like any other field
>> bale = HayBale.objects.create(weight=1.2)
>> bale = HayBale.objects.first()
>> bale.weight
<Quantity(1.2, 'tonne')>
>> bale.weight.magnitude
1.2
>> bale.weight.units
'tonne'
>> bale.weight.to('kilogram')
<Quantity(1200, 'kilogram')>
>> bale.weight.to('pound')
<Quantity(2645.55, 'pound')>
If your base unit is atomic (i.e. can be represented by an integer), you may also use IntegerQuantityField
and BigIntegerQuantityField
.
You can also pass Quantity objects to be stored in models. These are automatically converted to the units defined for the field ( but can be converted to something else when retrieved of course ).
>> from quantityfield.units import ureg
>> Quantity = ureg.Quantity
>> pounds = Quantity(500 * ureg.pound)
>> bale = HayBale.objects.create(weight=pounds)
>> bale.weight
<Quantity(0.226796, 'tonne')>
Use the inbuilt form field and widget to allow input of quantity values in different units
from quantityfield.fields import QuantityFormField
class HayBaleForm(forms.Form):
weight = QuantityFormField(base_units='gram', unit_choices=['gram', 'ounce', 'milligram'])
The form will render a float input and a select widget to choose the units.
Whenever cleaned_data is presented from the above form the weight field value will be a
Quantity with the units set to grams (values are converted from the units input by the user ).
You also can add the unit_choices
directly to the ModelField
. It will be propagated
correctly.
For comparative lookups, query values will be coerced into the correct units when comparing values, this means that comparing 1 ounce to 1 tonne should yield the correct results.
less_than_a_tonne = HayBale.objects.filter(weight__lt=Quantity(2000 * ureg.pound))
You can also use a custom Pint unit registry in your project settings.py
# project/settings.py
from pint import UnitRegistry
# django-pint will set the DJANGO_PINT_UNIT_REGISTER automatically
# as application_registry
DJANGO_PINT_UNIT_REGISTER = UnitRegistry('your_units.txt')
DJANGO_PINT_UNIT_REGISTER.define('beer_bootle_weight = 0.8 * kg = beer')
# app/models.py
class HayBale(models.Model):
# now you can use your custom units in your models
custom_unit = QuantityField('beer')
Note: As the documentation from pint states quite clearly: For each project there should be only one unit registry. Please note that if you change the unit registry for an already created project with data in a database, you could invalidate your data! So be sure you know what you are doing! Still only adding units should be okay.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django_pint-0.5b1-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8f17c03784499cd323643a3a260e7b94ca935942c1dc7759a4e5659c9d8954c9 |
|
MD5 | e170a4f62b33e17271779606a8c89b3f |
|
BLAKE2b-256 | f32cb5a5563deedd8d2ef4c7dff858daedcce266a8a4b72aa3e29012a48d94b8 |