Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#30125 closed Bug (invalid)

forms.DecimalField has incorrect validator

Reported by: Roman Paranichev Owned by: nobody
Component: Forms Version: 2.1
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

django-source: site-packages/django/core/validators.py:356

@deconstructible
class MinValueValidator(BaseValidator):
    message = _('Ensure this value is greater than or equal to %(limit_value)s.')
    code = 'min_value'
    def compare(self, a, b):
        return a < b

The message says 'Ensure this value is greater than or (!!!)equal(!!!)' but compare func make only 'Greater then' comparison.

Change History (3)

comment:1 by Tim Graham, 6 years ago

Resolution: invalid
Status: newclosed

The validator is correct. compare() returns True if the value is invalid. a is the value being validated and b is the limit value.

comment:2 by Roman Paranichev, 6 years ago

Steps to reproduce:

  1. create html form
<form action="/payment/">
<input type="number" step="0.01" name="amount" value="0.01" required>
<input type="submit" value="Submit">
</form>
  1. create django-form for validation:
from django import forms

class CreatePaymentForm(forms.Form):
    amount = forms.DecimalField(min_value=0.02, max_digits=12, decimal_places=2)
  1. Try to validate from in a view class:
import json
from django.http import HttpResponse
from django.views.generic import View
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from api.forms import CreatePaymentForm

@method_decorator(login_required, name='dispatch')
@method_decorator(csrf_exempt, name='dispatch')
class PaymentView(View):

    def post(self, request):
        form = CreatePaymentForm(request.POST)
        if form.is_valid():
              pass
        print("post: %s, errors: %s" % (request.POST, form.errors))
        return HttpResponse(json.dumps({'errors': form.errors}), status=400)

The output will be:
post: <QueryDict: {'amount': ['0.02']}>, errors: <ul class="errorlist"><li>amount<ul class="errorlist"><li>Ensure this value is greater than or equal to 0.02.</li></ul></li></ul>

Last edited 6 years ago by Roman Paranichev (previous) (diff)

comment:3 by Tim Graham, 6 years ago

Please try with min_value=Decimal('0.02') -- floats like 0.02 may not keep precision. A better test would use MinValueValidator directly rather than require a full request/response -- see tests/validators in Django's source code.

Note: See TracTickets for help on using tickets.
Back to Top