Welcome to django-fractions’s documentation!¶
Contents:
django-fractions¶

Fraction display and form fields for Django
Documentation¶
The full documentation is at https://django-fractions.readthedocs.org.
Quickstart¶
Install django-fractions:
pip install django-fractions
Add djfractions
to settings.INSTALLED_APPS
Then use it in a project:
import djfractions
In templates:
{% load fractions %}
{% display_fraction 1.25 %}
In Forms:
from djfractions.forms import DecimalFractionField
from django import forms
class MyForm(forms.Form):
a_fraction = DecimalFractionField()
Features¶
- Template tag for displaying float and Decimal values as fractions including mixed numbers
- DecimalFractionField form field which handles input such as “1/4”, “1 1/2”, “1 and 1/2”, and converts to a decimal.Decimal instance
TODO¶
- Add unicode_fraction template tag to display the unicode fraction entity if available
- forms.FloatDecimalField to return a float rather than Decimal
- forms.SplitFractionWidget for having separate numerator and denominator form fields
- forms.SplitMixedFractionWidget for handling mixed number fractions with separate fields
- models.DecimalBackedFractionField() to store a Decimal value but return/accept it as a fraction
- models.FloatBackedFractionField() to store a Decimal value but return/accept it as a fraction
Cookiecutter Tools Used in Making This Package¶
- cookiecutter
- cookiecutter-djangopackage
Installation¶
At the command line:
$ easy_install django-fractions
Or, if you have virtualenvwrapper installed:
$ mkvirtualenv django-fractions
$ pip install django-fractions
After installation add djfractions
to your settings.INSTALLED_APPS
Usage¶
Add djfractions
to settings.INSTALLED_APPS
Model Fields¶
DecimalFractionField¶
djfractions.models.DecimalFractionField(verbose_name=None,
name=None,
max_digits=None,
decimal_places=None,
limit_denominator=None,
coerce_thirds=True,
**kwargs)
Takes a fractions.Fraction
value, stores it as a decimal value,
and then returns it as a fractions.Fraction
. This field is highly
based on Django’s models.DecimalField
implementation and so
the max_digits and decimal_places arguments are required.
param str verbose_name: | |
---|---|
The verbose name of the field | |
param str name: | Name of the field |
param int max_digits: | |
Maximum number of digits to use for the Decimal representation | |
param int decimal_places: | |
Maximum number of decimal places to use for the Decimal representation | |
param int limit_denominator: | |
Limits the fraction’s denominator to this value if it is set. | |
paraam bool coerce_thirds: | |
If True, then when values which appear to be Decimal values which started as 1/3 or 2/3 will be forced back to 1/3 or 2/3 when retrieved from the database. |
Form Fields¶
FractionField¶
FractionField(max_value=None,
min_value=None,
coerce_thirds=True,
limit_denominator=None,
use_mixed_numbers=True)
Returns a fractions.Fraction
instance. Takes a string formatted
as a fraction such as 1/4, 1 1/4, 1-1/4, 1 and 1/4, or -1/4 as input in a form.
param Decimal max_value: | |
---|---|
The maximum value allowed for this field | |
param Decimal min_value: | |
The minimum value allowed for this field | |
param int limit_denominator: | |
Limits the fraction’s denominator to this value if it is set. | |
param bool coerce_thirds: | |
If True, then when values which appear to be Decimal values which started as 1/3 or 2/3 will be forced back to 1/3 or 2/3 when retrieved from the database. | |
param bool use_mixed_numbers: | |
If True initial values which are decimals and floats greater than 1 will be converted to a mixed number such as 1 1/2 in the form field’s value. If False then improper fractions such as 3/2 will be created. Defaults to True. |
Example:
from django import forms
from djfractions.forms import FractionField
class MyForm(forms.Form):
a_fraction = FractionField()
DecimalFractionField¶
DecimalFractionField(max_value=None,
min_value=None,
coerce_thirds=True,
limit_denominator=None,
use_mixed_numbers=True,
max_digits=None,
decimal_places=None)
Returns a decimal.Decimal
instance. Takes a string formatted
as a fraction such as 1/4, 1 1/4, 1-1/4, 1 and 1/4, or -1/4 as input in a form.
param bool coerce_thirds: | |
---|---|
Defaults to True. If True then .3 repeating is forced to 1/3 rather than 3/10, 33/100, etc. and .66 and .67 are forced to 2/3. | |
param int limit_denominator: | |
Set a maximum denominator to be used on fractions created from the field input. | |
param bool use_mixed_numbers: | |
If True initial values which are decimals and floats greater than 1 will be converted to a mixed number such as 1 1/2 in the form field’s value. If False then improper fractions such as 3/2 will be created. Defaults to True. | |
param max_value: | |
The maximum value allowed | |
param min_value: | |
The minimum value allowed | |
param int decimal_places: | |
The maximum number of decimal places the resulting Decimal value may have | |
param int max_digits: | |
The maximum number of digits, including decimal places, the resulting Decimal may have. |
Example:
from django import forms
from djfractions.forms import DecimalFractionField
class MyForm(forms.Form):
a_fraction = DecimalFractionField()
Template Tags¶
display_fraction¶
{% display_fraction value limit_denominator allow_mixed_numbers coerce_thirds %}
The display_fraction tag displays a formatted fraction in an HTML template. It takes a value and optional parameters to limit the denominator, allow mixed numbers, and adjust decimal/float values which usually are the result of rounding thirds back to thirds based fractions.
The output of this tag can be changed by overriding the djfractions/display_fraction.html
template. This is because there are a number of style choices you might make depending
on needs. In some cases <sup> and <sub> tags may cause issues with screen readers. You
may just want to add css classes for easier styling. The template context also includes
a unicode_entity
value which has the html entity for the unicode value of a fraction
if one is available. The unicode html entity is preferred by some people, but only a
small number of fractions are supported (particularly if you must support very old browsers)
and the styling is frequently difficult to match up exactly with <sup> and <sub> tags.:
{% load fractions %}
{% display_fraction 1.5 %}
Would output:
1 <sup>1</sup>⁄<sub>2</sub>
The template context:
- whole_number
- The whole number part of a fraction. If
allow_mixed_numbers
is False then this will always be 0. - numerator
- The numerator of a fraction. For values which are only a whole number the numerator will be 0.
- denominator
- The denominator of a fraction. For values which are only a whole number the denominator will be 1 for a fraction of 0/1.
- unicode_entity
- The unicode_entity is the html entity for the unicode fraction if one exists.
- allow_mixed_numbers
- The value passed to the tag for
allow_mixed_numbers
. Knowing this can be useful in template display logic.
The following unicode fraction HTML entities are supported by django-fractions. They may not all be supported by your browser.
Entity | IE 11 | Firefox 39 | Chrome 44 |
---|---|---|---|
½ | Yes | Yes | Yes |
⅓ | Yes | Yes | Yes |
⅔ | Yes | Yes | Yes |
¼ | Yes | Yes | Yes |
¾ | Yes | Yes | Yes |
⅕ | Yes | Yes | Yes |
⅖ | Yes | Yes | Yes |
⅗ | Yes | Yes | Yes |
⅘ | Yes | Yes | Yes |
⅙ | Yes | Yes | Yes |
⅚ | Yes | Yes | Yes |
&frac17; | No | No | Yes |
⅛ | Yes | Yes | Yes |
⅜ | Yes | Yes | Yes |
⅝ | Yes | Yes | Yes |
⅞ | Yes | Yes | Yes |
display_improper_fraction¶
{% display_improper_fraction value limit_denominator coerce_thirds %}
The display_improper_fraction tag works the same as display_fraction with its allow_mixed_numbers set to False. It is just a shortcut for a common use case.:
{% load fractions %}
{% display_improper_fraction 1.5 %}
Would output:
<sup>3</sup>⁄<sub>2</sub>
Contributing¶
Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.
You can contribute in many ways:
Types of Contributions¶
Report Bugs¶
Report bugs at https://github.com/jmichalicek/django-fractions/issues.
If you are reporting a bug, please include:
- Your operating system name and version.
- Any details about your local setup that might be helpful in troubleshooting.
- Detailed steps to reproduce the bug.
Fix Bugs¶
Look through the GitHub issues for bugs. Anything tagged with “bug” is open to whoever wants to implement it.
Implement Features¶
Look through the GitHub issues for features. Anything tagged with “feature” is open to whoever wants to implement it.
Write Documentation¶
django-fractions could always use more documentation, whether as part of the official django-fractions docs, in docstrings, or even on the web in blog posts, articles, and such.
Submit Feedback¶
The best way to send feedback is to file an issue at https://github.com/jmichalicek/django-fractions/issues.
If you are proposing a feature:
- Explain in detail how it would work.
- Keep the scope as narrow as possible, to make it easier to implement.
- Remember that this is a volunteer-driven project, and that contributions are welcome :)
Get Started!¶
Ready to contribute? Here’s how to set up django-fractions for local development.
These instructions are out of date. I have moved to developing in a docker container in a docker compose stack. I have not yet set that up to deal with multiple Python versions for tox.
Fork the django-fractions repo on GitHub.
Clone your fork locally:
$ git clone git@github.com:your_name_here/django-fractions.git
Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:
$ mkvirtualenv django-fractions $ cd django-fractions/ $ python setup.py develop
Create a branch for local development:
$ git checkout -b name-of-your-bugfix-or-feature
Now you can make your changes locally.
5. When you’re done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:
$ flake8 djfractions tests
$ python setup.py test
$ tox
To get flake8 and tox, just pip install them into your virtualenv.
Commit your changes and push your branch to GitHub:
$ git add . $ git commit -m "Your detailed description of your changes." $ git push origin name-of-your-bugfix-or-feature
Submit a pull request through the GitHub website.
Pull Request Guidelines¶
Before you submit a pull request, check that it meets these guidelines:
- The pull request should include tests.
- If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.rst.
- The pull request should work for Python 2.7, 3.3, and 3.4. Check https://travis-ci.org/jmichalicek/django-fractions/pull_requests and make sure that the tests pass for all supported Python versions.
Credits¶
Development Lead¶
- Justin Michalicek <jmichalicek@gmail.com>
Contributors¶
None yet. Why not be the first?
History¶
Current¶
5.0.0 (2023-01-08)¶
- Forgot about the 4.0.0 mess when I published 3.1.0, so starting fresh again. There are not really any backwards incompatible changes. See the 3.1.0 release notes.
- Fixing documentation and release history.
4.0.0 (2022-08-10)¶
- I’m dumb and goofed thing up and so this version exists on pypi
3.1.0 (2022-12-26)¶
- Add testing on python 3.11 by @jmichalicek in #30
- Fixed ‘Polynomial regular expression used on uncontrolled data’ codeQL issues which could be abused to impact performance.
3.0.0 (2022-08-10)¶
- Create codeql-analysis.yml by @jmichalicek in #21
- Add type checking by @jmichalicek in #22
- Update supported python versions to 3.7+ by @jmichalicek in #23
- fix: Django 4.0 deprecations by @GriceTurrble in #24
- Add testing of django 4.0 by @jmichalicek in #27
- Updated to support Django 4.1, drop old unsupported Django and Python versions by @jmichalicek in #29
2.0.0 (2020-09-13)¶
- Dropped support for Django 2.0 and lower and bump major version
- Dropped support for Python 3.4 and lower
- Updated DecimalFractionField to work on Django 2+ where from_db_field() does not take a context argument and where the field is expected to have a context attribute like DecimalField.
- Cleared out a bunch of Python 2 compatibility code such as how calls to super() are made, usage of six, and from __future__ imports.
1.1.0 (2017-06-04)¶
- add python 3.6 and django 1.11 to tox.ini - still a bit broken
- convert to matrix for environments in .travis.yml because tox only wants to test py3.6 when installed under 3.6 but will not test 3.5 when running with python 3.6 as the base.
- Remove invalid ROOT_URLCONF from test django config There is no urls.py for djfractions, don’t tell it to use one. Older django versions were ok with this, but 1.11 is pickier about the correctness.
- add current changes to HISTORY.rst
- Adjust SILENCED_SYSTEM_CHECKS setting during tests Django 1.11 is stricter about system checks and will not even run the tests where there are some errors we specifically test for due to older django versions letting you make these mistakes.
- Added optional max_digits and decimal_places parameters to forms.DecimalFractionField so that returned Decimal objects have the desired max_digits and decimal_places when not directly tied to a models.DecimalField() on a ModelForm
1.0.0 (2016-12-31)¶
- Stop subclassing Django’s DecimalField and duplicate small amounts of code as necessary for db backend compatibility. Too many things need to be handled differently. Main cause of major version bump.
- Update forms.FractionField to skip over max_digits and decimal_places kwargs which will get passed in by models.fields.DecimalFractionField
- Add models.fields.DecimalFractionField.formfield() so that a forms.FractionField will be used by default
- Fix quantity_to_decimal and quantity_to_fraction to strip leading and trailing spaces before pattern matching and converting to a decimal or fraction
- Allow for leading negative sign with forms.FractionField input values
- Fix is_fraction() to allow leading negative sign
- Add max_digits and decimal_places params to DecimalFractionField in test model
- Additional test cases for models.fields.DecimalFractionField
0.4.0 (2016-08-29)¶
- Added djfractions.models.DecimalFractionField which stores fractions.Fraction values as decimals in the dataase.
- Better usage of tox to test against different Python and Django versions
- Added testing against Django 1.10
0.3.2 (2015-08-28)¶
- Fixed boolean logic for when to coerce values to thirds in in forms.DecimalFractionField and get_fraction_parts()
0.3.1 (2015-08-12)¶
- HISTORY.rst typo fixes
- pypi release version fix
0.3.0 (2015-08-12)¶
- Added forms.FractionField which returns fractions.Fraction instances
- Refactoring of common code with new forms.FractionField
- Smarter checking for numeric types throughout the code
- forms.DecimalFractionField.to_python() handles fractions.Fraction values now
- Fixed bug handling negative numbers in quantity_to_decimal()
- Added min_value and max_value to forms.DecimalFractionField
- Made coerce_thirds, limit_denominator, and use_mixed_numbers params to DecimalFractionField proper named parameters and not just kwargs.
0.2.1 (2015-08-06)¶
- Fixed typo in usage docs
0.2.0 (2015-08-06)¶
- display_fraction template tag output is templated so that its formatting can be changed by users
- Added new display_improper_fraction template tag to simplify the common case of wanting to only use improper fractions with no whole numbers
- Added unicode_entity to template context for display_fraction and display_improper_fraction so that the html entity for common fractions may be used rather than <sup> and <sub> tags
- Refactored lots of code out into smaller, reusable functions
- Added a bunch of test cases
0.1.0 (2015-08-01)¶
- First release on PyPI.