Skip to content

Instantly share code, notes, and snippets.

@pezon
Last active December 27, 2015 15:09
Show Gist options
  • Save pezon/7345072 to your computer and use it in GitHub Desktop.
Save pezon/7345072 to your computer and use it in GitHub Desktop.
human write-able integer field for django admin. can also rip the individual dehumanize() function for standalone use.
from django import forms
from django.contrib import admin
from project.app.models import Foo
from project.app.forms import HumanIntegerField
class FooAdminForm(forms.ModelForm):
class Meta:
model = Foo
bar_field = HumanIntegerField()
class FooAdmin(admin.ModelAdmin):
form = FooAdminForm
import re
import locale
from django import forms
from django.core.exceptions import ValidationError
locale.setlocale(locale.LC_ALL, 'en_US.UTF8')
def dehumanize_number(number):
number = number.strip()
if re.match("^[0-9,]+$", number): # regular numbers, number with commas
return locale.atof(number)
illions = (
('k', ('thousand', 'k', 'g'), 1000),
('m', ('million', 'mil', 'mn', 'm'), 1000000),
('b', ('billion', 'bil', 'bn', 'b'), 1000000000),
('t', ('trillion', 'tril', 'tn', 't'), 1000000000000)
)
number = number.lower()
for illion in illions:
shorthand, matches, convert = illion
for match in matches:
if match in number:
number = number.replace(match, shorthand)
m = re.match('^([0-9.]+)\s?[kmbt]$', number)
if m and m.group(1):
number = float(m.group(1)) * convert
return number
return number
class HumanIntegerField(forms.IntegerField):
def __init__(self, *args, **kwargs):
super(HumanIntegerField, self).__init__(*args, **kwargs)
locale.setlocale(locale.LC_ALL, 'en_US.UTF8')
def clean(self, number):
number = int(dehumanize_number(number))
return super(HumanIntegerField, self).clean(number)
class HumanDecimalField(forms.DecimalField):
def __init__(self, *args, **kwargs):
super(HumanDecimalField, self).__init__(*args, **kwargs)
locale.setlocale(locale.LC_ALL, 'en_US.UTF8')
def clean(self, number):
number = dehumanize_number(number)
return super(HumanDecimalField, self).clean(number)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment