CarliJoy / django-pint

Simple django app for storing Quantities with units, leveraging the Pint library
https://django-pint.readthedocs.io
MIT License
38 stars 16 forks source link

Same Attrs are set for both parts of MultiWidget #102

Open mmarras opened 1 month ago

mmarras commented 1 month ago
class QuantityWidget(MultiWidget):
    def __init__(self, *, attrs=None, base_units=None, allowed_types=None):
        self.ureg = ureg
        choices = self.get_choices(allowed_types)
        self.base_units = base_units
        attrs = attrs or {}
        attrs.setdefault("step", "any")

        ### LOOK HERE
        widgets = (NumberInput(attrs=attrs), Select(attrs=attrs, choices=choices))
        ###

        super(QuantityWidget, self).__init__(widgets, attrs)

    def get_choices(self, allowed_types=None):
        allowed_types = allowed_types or dir(self.ureg)
        return [(x, x) for x in allowed_types]

    def decompress(self, value):
        """This function is called during rendering

        It is responsible to split values for the two widgets
        """
        if isinstance(value, Number):
            # We assume that the given value is a proper number,
            # ready to be rendered
            return [value, self.base_units]
        elif isinstance(value, pint.Quantity):
            return [value.magnitude, value.units]

        return [None, self.base_units]

There is no way to define individual attributes to the NumberInput or Select tag because both are fed the same attribute dictionary.

I suggest to split that up, since both are different types which may require different attributes in the html tag.

mmarras commented 1 month ago

Possibly this has to solved on Django level tho. Still looking into it...

mmarras commented 1 month ago

https://code.djangoproject.com/ticket/5851#comment:14

according to this MultiWidget should be able to handle individual attrs...

CarliJoy commented 1 month ago

The related commit shows:

    def __init__(self, attrs=None, date_format=None, time_format=None, date_attrs=None, time_attrs=None):
        widgets = (
            DateInput(
                attrs=attrs if date_attrs is None else date_attrs,
                format=date_format,
            ),
            TimeInput(
                attrs=attrs if time_attrs is None else time_attrs,
                format=time_format,
            ),
        )
        super().__init__(widgets)

Feel free to adopt.