Opened 14 months ago

Last modified 8 months ago

#34853 closed Bug

[Date Input Localization] Accept-Language Header Takes Precedence Over Language Set With Cookie — at Version 2

Reported by: blue-hexagon Owned by: nobody
Component: Internationalization Version: dev
Severity: Normal Keywords: l10n format localization
Cc: Claude Paroz Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: yes

Description (last modified by blue-hexagon)

Accept-Language Header takes precedence over language set with cookie

The input localization follows the browsers locale.

In the first image below, my browsers locale is 'da' (Danish/Dansk) while Django language is en-GB - the form inputs should be localized to en-GB and *not* danish!

In the second image, my browsers locale is 'en-GB' and Django language is 'da' (Danish) - the form inputs should be localized to danish and not en-GB!

The images clearly shows the error.

I have provided every relevant piece of information I can think of below the images.

Nowhere in the Django docs, does it mention that form inputs should be localized to the browsers locale.

Image 1
https://i.imgur.com/twLMfDc.png

Image 2
https://i.imgur.com/HnE2HgC.png

Middleware

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.middleware.gzip.GZipMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    'django.middleware.locale.LocaleMiddleware',
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    "django.middleware.common.BrokenLinkEmailsMiddleware",
]

I18N / L10N

TIME_ZONE = "UTC"
LANGUAGE_CODE = "en"
LANGUAGES = [
    ('en', _('English')),
    ('en-gb', _('English')),
    ('da', _('Danish')),
]

USE_I18N = True
LANGUAGE_COOKIE_AGE = 31_536_000  # 1 year.

USE_L10N = True
USE_THOUSAND_SEPARATOR = True
USE_TZ = True

LOCALE_PATHS = [
    BASE_DIR / 'locale/',
]

Loan View

@login_required(login_url="/accounts/login/")
def loan_create(request, institution_id: int):
    if request.POST:
        form = LoanForm(request.POST)
        if form.is_valid():
            form.save()
            messages.add_message(request, messages.SUCCESS, _("Loan created successfully."))
            return redirect(request.META.get("HTTP_REFERER", request.path_info))
        else:
            messages.add_message(request, messages.ERROR, _("An error occured."))
            return redirect(request.META.get("HTTP_REFERER", request.path_info))
    form = LoanFormCreate(
        institution_id=institution_id,
        initial={
            "staff": request.user.id,
            "reminder_has_been_sent": 0,
            "is_returned": False,
        },
    )
    return render(
        request,
        template_name="crud/loan/create.html",
        context={
            "form": form,
        },
    )

Modelforms for Loan

class LoanForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    class Meta:
        model = Loan
        fields = "__all__"


class LoanFormBase(ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    class Meta:
        localized_fields = [
            "borrowed_from_date",
            "borrowed_to_date",
            "deposit"
        ]
        model = Loan
        fields = [
            "id",
            "borrower_user",
            "staff_user",
            "item",
            "borrowed_from_date",
            "borrowed_to_date",
            "reminder_has_been_sent",
            "is_returned",
            "extra_information",
            "deposit",
        ]
        widgets = {
            "id": forms.NumberInput(),
            "staff_user": forms.Select(attrs={"class": "form-control"}),
            "borrower_user": forms.Select(attrs={"class": "form-control"}),
            "item": forms.Select(attrs={"class": "form-control", "data-live-search": True}),
            "borrowed_from_date": forms.DateInput(
                attrs={"class": "form-control", "type": "date"}, format=locale_format
            ),
            "borrowed_to_date": forms.DateInput(attrs={"class": "form-control", "type": "date"}),
            "reminder_has_been_sent": forms.NumberInput(attrs={"class": "form-control "}),
            "is_returned": forms.CheckboxInput(attrs={"class": "form-control"}),
            "extra_information": forms.Textarea(attrs={"class": "form-control", "rows": 4}),
            "deposit": forms.TextInput(attrs={"class": "form-control"}),
        }
        labels = {
            "staff_user": _("Lender"),
            "borrower_user": _("Borrower"),
            "item": _("Loaned Asset"),
            "borrowed_from_date": _("Loaned From"),
            "borrowed_to_date": _("Loaned To"),
            "is_returned": _("Returned"),
            "extra_information": _("Comments"),
            "deposit": _("Deposit"),
            "reminder_has_been_sent": _("Reminder Sent"),
        }

        help_texts = {
            "staff_user": _("Select the person responsible for lending the asset to the borrower."),
            "borrower_user": _("Select the person who borrowed the asset."),
            "item": _("Select the asset that has been loaned out."),
            "borrowed_from_date": _("Pick the date when the asset was borrowed."),
            "borrowed_to_date": _("Pick the expected return date for the asset."),
            "is_returned": _("Check this box when the asset has been returned."),
            "extra_information": _("Add any relevant comments or additional information about the loan here."),
            "deposit": _("Enter the deposit amount, if applicable."),
            "reminder_has_been_sent": _("Check if a reminder has been sent for this loan."),
        }


class LoanFormCreate(LoanFormBase):
    def __init__(self, institution_id: int, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Items shall belong to the institution
        self.fields["item"].queryset = Item.objects.filter(item_group__institution_id=institution_id)

        # Borrower users shall belong to the institution
        self.fields["borrower_user"].queryset = User.objects.filter()
        institution_staff_ids = StaffInstitution.objects.filter().values_list("staff_id")
        self.fields["staff_user"].queryset = User.objects.filter().exclude()

    class Meta(LoanFormBase.Meta):
        localized_fields = [
            "borrowed_from_date",
            "borrowed_to_date",
            "deposit"
        ]
        exclude = ["id", "is_returned"]
        widgets = {
            "extra_information": forms.Textarea(attrs={"class": "form-control", "rows": 4}),
            "borrowed_from_date": forms.DateInput(
                attrs={"class": "form-control", "type": "date"},
            ),
            "borrowed_to_date": forms.DateInput(
                attrs={"class": "form-control", "type": "date"},
            ),
            "item": forms.Select(
                attrs={
                    "class": "form-control selectpicker border",
                    "data-live-search": "true",
                    "data-show-subtext": "true",
                    "data-style": "form-control",
                }
            ),
            "borrower_user": forms.Select(
                attrs={
                    "class": "form-control selectpicker border",
                    "data-live-search": "true",
                    "data-show-subtext": "true",
                    "data-style": "form-control",
                }
            ),
            "staff_user": forms.Select(
                attrs={
                    "class": "form-control selectpicker border ",
                    "data-live-search": "true",
                    "data-show-subtext": "true",
                    "data-style": "form-control",
                    "": "",
                }
            ),
            "reminder_has_been_sent": forms.NumberInput(attrs={"hidden": None}),
        }

Input Dates in Images from HTML file

{# ---------------------------------------------------- #}
{# --- Trying out with and without filters and tags --- #}
{{ form.borrowed_to_date }}
{{ form.borrowed_to_date|localize }}
{% localize off %}
{{ form.borrowed_to_date }}
{% endlocalize %}
{% localize on %}
{{ form.borrowed_to_date }}
{% endlocalize %}
{# ---------------------------------------------------- #}

Change History (2)

comment:1 by blue-hexagon, 14 months ago

Type: UncategorizedBug

comment:2 by blue-hexagon, 14 months ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top