﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
24636	Add validator to DecimalField to ensure that it respects max_digits/decimal_places	Marc Aymerich	Simon Charette	"I get an InvalidOperation exception when trying to save a particular decimal field.



{{{
Traceback:
File ""/usr/local/lib/python3.4/dist-packages/django/core/handlers/base.py"" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File ""/usr/local/lib/python3.4/dist-packages/django/contrib/admin/options.py"" in wrapper
  616.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File ""/usr/local/lib/python3.4/dist-packages/django/utils/decorators.py"" in _wrapped_view
  110.                     response = view_func(request, *args, **kwargs)
File ""/usr/local/lib/python3.4/dist-packages/django/views/decorators/cache.py"" in _wrapped_view_func
  57.         response = view_func(request, *args, **kwargs)
File ""/usr/local/lib/python3.4/dist-packages/django/contrib/admin/sites.py"" in inner
  233.             return view(request, *args, **kwargs)
File ""/home/orchestra/django-orchestra/orchestra/contrib/accounts/admin.py"" in changelist_view
  286.                 extra_context=context)
File ""/usr/local/lib/python3.4/dist-packages/django/utils/decorators.py"" in _wrapper
  34.             return bound_func(*args, **kwargs)
File ""/usr/local/lib/python3.4/dist-packages/django/utils/decorators.py"" in _wrapped_view
  110.                     response = view_func(request, *args, **kwargs)
File ""/usr/local/lib/python3.4/dist-packages/django/utils/decorators.py"" in bound_func
  30.                 return func.__get__(self, type(self))(*args2, **kwargs2)
File ""/usr/local/lib/python3.4/dist-packages/django/contrib/admin/options.py"" in changelist_view
  1590.                 response = self.response_action(request, queryset=cl.get_queryset(request))
File ""/usr/local/lib/python3.4/dist-packages/django/contrib/admin/options.py"" in response_action
  1333.             response = func(self, request, queryset)
File ""/home/orchestra/django-orchestra/orchestra/contrib/orders/actions.py"" in __call__
  32.         return self.set_options(request)
File ""/home/orchestra/django-orchestra/orchestra/contrib/orders/actions.py"" in set_options
  48.                     return self.confirmation(request)
File ""/usr/lib/python3.4/contextlib.py"" in inner
  30.                 return func(*args, **kwds)
File ""/home/orchestra/django-orchestra/orchestra/contrib/orders/actions.py"" in confirmation
  80.             bills = self.queryset.bill(commit=True, **self.options)
File ""/home/orchestra/django-orchestra/orchestra/contrib/orders/models.py"" in bill
  44.                 bills += bill_backend.create_bills(account, bill_lines, **options)
File ""/home/orchestra/django-orchestra/orchestra/contrib/orders/billing.py"" in create_bills
  45.                     order_billed_until=line.order.old_billed_until
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/fields/related.py"" in create
  750.             return super(RelatedManager, self.db_manager(db)).create(**kwargs)
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/manager.py"" in manager_method
  127.                 return getattr(self.get_queryset(), name)(*args, **kwargs)
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/query.py"" in create
  348.         obj.save(force_insert=True, using=self.db)
File ""/home/orchestra/django-orchestra/orchestra/contrib/bills/models.py"" in save
  321.         super(BillLine, self).save(*args, **kwargs)
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/base.py"" in save
  710.                        force_update=force_update, update_fields=update_fields)
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/base.py"" in save_base
  738.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/base.py"" in _save_table
  822.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/base.py"" in _do_insert
  861.                                using=using, raw=raw)
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/manager.py"" in manager_method
  127.                 return getattr(self.get_queryset(), name)(*args, **kwargs)
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/query.py"" in _insert
  920.         return query.get_compiler(using=using).execute_sql(return_id)
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/sql/compiler.py"" in execute_sql
  962.             for sql, params in self.as_sql():
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/sql/compiler.py"" in as_sql
  920.                 for obj in self.query.objs
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/sql/compiler.py"" in <listcomp>
  920.                 for obj in self.query.objs
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/sql/compiler.py"" in <listcomp>
  918.                     ) for f in fields
File ""/usr/local/lib/python3.4/dist-packages/django/db/models/fields/__init__.py"" in get_db_prep_save
  1627.                 self.max_digits, self.decimal_places)
File ""/usr/local/lib/python3.4/dist-packages/django/db/backends/base/operations.py"" in value_to_db_decimal
  477.         return utils.format_number(value, max_digits, decimal_places)
File ""/usr/local/lib/python3.4/dist-packages/django/db/backends/utils.py"" in format_number
  200.             value = value.quantize(decimal.Decimal("".1"") ** decimal_places, context=context)

Exception Type: InvalidOperation at /admin/orders/order/
Exception Value: [<class 'decimal.InvalidOperation'>]
}}}


{{{
decimal_places	2
context	        Context(prec=2, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, InvalidOperation, Rounded], traps=[InvalidOperation, DivisionByZero, Overflow])
value	        Decimal('21')
max_digits	2
}}}



{{{
Django Version: 1.8.1
Python Version: 3.4.2
}}}
"	Bug	closed	Database layer (models, ORM)	dev	Normal	fixed	InvalidOperation decimal Decimal		Ready for checkin	1	0	0	0	0	0
