Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DateTimeWidget breaks DateTimeField with a list format #910

Closed
antoinelaborde opened this issue Dec 21, 2024 · 2 comments
Closed

DateTimeWidget breaks DateTimeField with a list format #910

antoinelaborde opened this issue Dec 21, 2024 · 2 comments

Comments

@antoinelaborde
Copy link

unfold version: 0.43.0
django version: 5.1.4
browser: Version 1.73.104 Chromium: 131.0.6778.204 (Build officiel) (arm64)
checked other issues: Yes
checked documentation: Yes

Issue description

Context

I'm building a custom Django Form and defined a django.forms.DateTimeField with a UnfoldAdminSplitDateTimeVerticalWidget as a widget:

expired_at = forms.DateTimeField(
        label=_("Expiration date time"),
        help_text=_("When the request expires"),
        required=False,
        widget=UnfoldAdminSplitDateTimeVerticalWidget(
            date_attrs={"type": "date"}, time_attrs={"type": "time"},
        )
    )

My goal is to obtain a field with Date and Time input using the Unfold component (as we can have on the demo site on date field) and returning the datetime value to my form.

Problem

When submitting the form, the form the following error happened:

'list' object has no attribute 'strip'

Traceback:
/.../lib/python3.12/site-packages/django/forms/fields.py

            return None
        if isinstance(value, datetime.datetime):
            return from_current_timezone(value)
        if isinstance(value, datetime.date):
            result = datetime.datetime(value.year, value.month, value.day)
            return from_current_timezone(result)
        try:
            result = parse_datetime(value.strip())
                                         ^^^^^^^^^^^ …
        except ValueError:
            raise ValidationError(self.error_messages["invalid"], code="invalid")
        if not result:
            result = super().to_python(value)
        return from_current_timezone(result)

When I look at the POST data in the debug mode I've found this:

expired_at_0 | '2024-12-20'
expired_at_1 | '10:58'

the date and time input are provided to the form in two different keys.
As a consequence, the Field method to_python has to deal with the list: ['2024-12-20', '10:58'] which it cannot handle.

I had to overwrite the to_python method like this to make it works:

class CustomDateTimeField(forms.DateTimeField):
    """Custom DateTime Field to handle date and time data in list value"""
    def to_python(self, value):
        """Handle date and time put in a list which is not handled by the generic field"""
        value = datetime.strptime(f"{value[0]}T{value[1]}", "%Y-%m-%dT%H:%M")
        super().to_python(value)

I suggest it is a bug because I can see the Date and Time widget from Unfold (although I don't know which class is used exactly) in a form is working well because default creation forms seem to use it. So maybe I'm using it wrong here. However, if it is the case, maybe UnfoldAdminSplitDateTimeVerticalWidget should be more straightforward to use.

@lukasvinclav
Copy link
Contributor

Are you using custom or localized datetime format? Few weeks ago I fixed something similar by adding new options to settings.py into Formula demo project:

https://github.com/unfoldadmin/formula/blob/main/src/formula/settings.py#L167

@antoinelaborde
Copy link
Author

Thanks for helping, I'm using standard datetime format.

However I've found the issue: I was using UnfoldAdminSplitDateTimeVerticalWidget with forms.DateTimeField which is not supported.
It seems that Widget with MultiWidgets must be used with suitable Fields, in my case: forms.SplitDateTimeFieldinstead of forms.DateTimeField.

This code is working well:

expired_at = forms.SplitDateTimeField(
        label=_("Expiration date time"),
        help_text=_("When the request expires"),
        required=False,
        widget=UnfoldAdminSplitDateTimeVerticalWidget(
            date_attrs={"type": "date"}, time_attrs={"type": "time"},
        )
    )

So this not a unfold issue but a Django one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants