简体   繁体   中英

Django: Authentication Form translated only locally?

I'm using the default Authentication form from Django.

This is the default implementation by Django of AuthenticationForm:

from django.contrib.auth.forms import AuthenticationForm 

I've translated the default error_messages to Spanish:

error_messages = {
            'invalid_login': _(
                "- Por favor, ingrese un nombre de usuario y contraseña correctos. "
                "- Diferencie entre minúsculas y mayúsculas."
            ),

However, when the app is uploaded to production (Heroku) these changes are not visible (it looks like it has been only applied locally).

Why?

class AuthenticationForm(forms.Form):
    """
    Base class for authenticating users. Extend this to get a form that accepts
    username/password logins.
    """
    username = UsernameField(widget=forms.TextInput(attrs={'autofocus': True}), label="Usuario")
    password = forms.CharField(
        label=_("Contraseña"),
        strip=False,
        widget=forms.PasswordInput,
    )

    error_messages = {
        'invalid_login': _(
            "- Por favor, ingrese un nombre de usuario y contraseña correctos. "
            "- Diferencie entre minúsculas y mayúsculas."
        ),
        'inactive': _("Esta cuenta no está activa."),
    }

    def __init__(self, request=None, *args, **kwargs):
        """
        The 'request' parameter is set for custom auth use by subclasses.
        The form data comes in via the standard 'data' kwarg.
        """
        self.request = request
        self.user_cache = None
        super().__init__(*args, **kwargs)

        # Set the max length and label for the "username" field.
        self.username_field = UserModel._meta.get_field(UserModel.USERNAME_FIELD)
        self.fields['username'].max_length = self.username_field.max_length or 254
        if self.fields['username'].label is None:
            self.fields['username'].label = capfirst(self.username_field.verbose_name)

    def clean(self):
        username = self.cleaned_data.get('username')
        password = self.cleaned_data.get('password')

        if username is not None and password:
            self.user_cache = authenticate(self.request, username=username, password=password)
            if self.user_cache is None:
                raise self.get_invalid_login_error()
            else:
                self.confirm_login_allowed(self.user_cache)

        return self.cleaned_data

    def confirm_login_allowed(self, user):
        """
        Controls whether the given User may log in. This is a policy setting,
        independent of end-user authentication. This default behavior is to
        allow login by active users, and reject login by inactive users.

        If the given user cannot log in, this method should raise a
        ``forms.ValidationError``.

        If the given user may log in, this method should return None.
        """
        if not user.is_active:
            raise forms.ValidationError(
                self.error_messages['inactive'],
                code='inactive',
            )

    def get_user(self):
        return self.user_cache

    def get_invalid_login_error(self):
        return forms.ValidationError(
            self.error_messages['invalid_login'],
            code='invalid_login',
            params={'username': self.username_field.verbose_name},
        )

The reason is because when you push to Heroku it does not push the changes you made in the default implementation. Instead it installs the default version of Django specified in your requirements.txt. So what you can do instead is create a custom AuthenticationForm that inherits from Django's default implementation, make the changes you require, and then specify this custom form in your urls:

# forms.py
from django.contrib.auth.forms import AuthenticationForm

class CustomAuthenticationForm(AuthenticationForm):
    username = UsernameField(widget=forms.TextInput(attrs={'autofocus': True}), label="Usuario")
    password = forms.CharField(
        label=_("Contraseña"),
        strip=False,
        widget=forms.PasswordInput,
    )

    error_messages = {
        'invalid_login': _(
            "- Por favor, ingrese un nombre de usuario y contraseña correctos. "
            "- Diferencie entre minúsculas y mayúsculas."
        ),
        'inactive': _("Esta cuenta no está activa."),
    }

    def __init__(self, request=None, *args, **kwargs):
        self.request = request
        self.user_cache = None
        super().__init__(*args, **kwargs)

        # Set the max length and label for the "username" field.
        self.username_field = UserModel._meta.get_field(UserModel.USERNAME_FIELD)
        self.fields['username'].max_length = self.username_field.max_length or 254
        if self.fields['username'].label is None:
            self.fields['username'].label = capfirst(self.username_field.verbose_name)


# urls.py
from .forms import CustomAuthenticationForm

url(r'^login/$', auth_views.LoginView.as_view(template_name='registration/login.html', authentication_form= CustomAuthenticationForm), name='login'),

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM