Percentage Field in Form

Dear all,
I created the following to have a PercentageField in my Form, with the proper validations, while saving it in the database as a fraction. After several tries I have the following solution.

class PercentageField(forms.DecimalField):
    """Form field that converts between percent (UI) and fraction (model)."""
    def __init__(self, *args, **kwargs):
        kwargs.setdefault('max_digits', 4)
        kwargs.setdefault('decimal_places', 1)
        kwargs.setdefault('widget', forms.NumberInput(attrs={'class': 'form-control'}))
        kwargs.setdefault('validators', [MinValueValidator(0), MaxValueValidator(100)])
        super().__init__(*args, **kwargs)

    def prepare_value(self, value):
        # Converts an internal fraction Decimal (e.g., Decimal('0.215'))
        # into a percentage Decimal for display by the widget.
        # This is called for initial form data.
        if value is None:
            return None
        print("Preparing value for percentage field")
       
        return (value * Decimal('100')).quantize(Decimal('0.1'))
       
    def clean(self, value):
        # This method is called when the form is validated.
        value = super().clean(value)
        if value is None:
            return None
        return Decimal(value) / Decimal('100')  # Convert percentage to fraction

    def bound_data(self, data, initial):
        # This method is called when the form is bound (e.g., on POST).
        # It provides the value that will be passed to the widget for redisplay if there are errors.
        # We return `data` (the raw user input string) to ensure the widget displays
        # exactly what the user typed, preventing `prepare_value` from re-multiplying it.
        return self.to_python(data) / Decimal('100.0')

Is this the way to do it? Or can I catch somewhere if the form is_bound in the prepare value?

Copilot suggested just to change the clean + prepare value functions for example, but this would result in multiplications on form errors. So a percentage entered as 10 became 1000 after the form was reprocessed with the error.