65 votes

Le nom d'utilisateur auth_user.username de django peut-il être varchar (75)? Comment cela pourrait-il être fait?

Est-il quelque chose de mal avec l'exécution de l'instruction alter table sur auth_user de faire username être de type varchar(75), afin de pouvoir s'adapter à un e-mail? Ce n'est que de se briser si quoi que ce soit?

Si vous deviez changer auth_user.nom d'utilisateur pour être de type varchar(75) où auriez-vous besoin de modifier django? Est-ce simplement une question de changement de 30 à 75 dans le code source?:

username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters"))

Ou est-il d'autres outils de validation sur ce domaine qui devrait être changé ou tout autre répercussions à agir de la sorte?

Voir le commentaire la discussion avec bartek ci-dessous concernant la raison de le faire.

Edit: en Regardant en arrière sur ce, après de nombreux mois. Pour ceux qui ne connaissent pas le principe: Certaines applications ne disposent pas d'une obligation ou le désir d'utiliser un nom d'utilisateur, ils n'utilisent que le courrier électronique pour l'enregistrement et l'authentification. Malheureusement, dans django auth.contrib, le nom d'utilisateur est requis. Vous pourriez commencer à mettre des e-mails dans le champ nom d'utilisateur, mais le champ est à seulement 30 char et les courriels peuvent être longues dans le monde réel. Peut-être même plus que les 75 char suggéré ici, mais 75 char adapte à la plupart des sane adresses e-mail. La question est destiné à cette situation, comme on l'a constaté par e-mail-auth-applications.

78voto

Clément Points 4224

Il y a une façon d'y parvenir sans toucher au modèle de base, et sans héritage, mais il est certainement hackish et je voudrais l'utiliser avec le plus grand soin.

Si vous regardez de Django reinhardt, doc sur les signaux, vous verrez qu'on appelait class_prepared, ce qui est fondamentalement envoyé une fois que toute la classe du modèle a été créé par la métaclasse. Ce moment, c'est votre dernière chance de modifier le modèle avant tout de la magie prend place (ie: ModelForm, ModelAdmin, syncdb, etc...).

Donc, le plan est simple, vous vous inscrivez simplement que le signal avec un gestionnaire qui permet de détecter quand il est appelé pour l' User modèle, puis changer l' max_length de la propriété de l' username champ.

Maintenant la question est de savoir où mettre ce code de vie? Il doit être exécutée avant que l' User modèle est chargé, donc, ce qui signifie souvent très tôt. Malheureusement, vous ne pouvez pas (django 1.1.1, n'est-ce pas vérifier avec une autre version) mettre en settings en raison de l'importation signals il y aura de la casse.

Un meilleur choix serait de le mettre dans un mannequin de l'application des modèles de module, et de mettre l'application sur le dessus de l' INSTALLED_APPS liste/n-uplet (de sorte qu'il devient importés avant toute autre chose). Voici un exemple de ce que vous pouvez avoir en myhackishfix_app/models.py :

from django.db.models.signals import class_prepared

def longer_username(sender, *args, **kwargs):
    # You can't just do `if sender == django.contrib.auth.models.User`
    # because you would have to import the model
    # You have to test using __name__ and __module__
    if sender.__name__ == "User" and sender.__module__ == "django.contrib.auth.models":
        sender._meta.get_field("username").max_length = 75

class_prepared.connect(longer_username)

Que va faire l'affaire.

Quelques remarques cependant:

  • Vous pouvez modifier également l' help_text du champ, afin de refléter la nouvelle longueur maximale
  • Si vous souhaitez utiliser l'automatique admin, vous aurez pour sous - UserChangeForm, UserCreationForm et AuthenticationForm la durée maximale n'est pas déduit du modèle de champ, mais directement dans le champ de formulaire de déclaration.

Si vous utilisez du Sud, vous pouvez créer de migration suivantes pour modifier la colonne de la base de données:

import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models

class Migration(SchemaMigration):

    def forwards(self, orm):

        # Changing field 'User.username'
        db.alter_column('auth_user', 'username', models.CharField(max_length=75))


    def backwards(self, orm):

        # Changing field 'User.username'
        db.alter_column('auth_user', 'username', models.CharField(max_length=35))


    models = { 

# ... Copy the remainder of the file from the previous migration, being sure 
# to change the value for auth.user / usename / maxlength

25voto

skoczen Points 425

Sur la base de l'excellente réponse combinée de Clément et Matt Miller ci-dessus, j'ai créé une application rapide qui la met en œuvre. Pip installer, migrer, et c'est parti. Je mettrais cela comme un commentaire, mais vous n'avez pas encore le crédit!

https://github.com/GoodCloud/django-longer-username

21voto

kottenator Points 1298

Solution mise à jour pour la version Django 1.3 (sans modifier manage.py):

Créer un nouveau Django-app:

 monkey_patch/
    __init__.py
    models.py
 

Installez-le en tant que premier: (settings.py)

 INSTALLED_APPS = (
    'monkey_patch', 
    #...
)
 

Voici models.py:

 from django.contrib.auth.models import User
from django.core.validators import MaxLengthValidator

NEW_USERNAME_LENGTH = 300

def monkey_patch_username():
    username = User._meta.get_field("username")
    username.max_length = NEW_USERNAME_LENGTH
    for v in username.validators:
        if isinstance(v, MaxLengthValidator):
            v.limit_value = NEW_USERNAME_LENGTH

monkey_patch_username()
 

5voto

Cerin Points 9851

Les solutions ci-dessus semblent mettre à jour la longueur du modèle. Cependant, pour refléter votre longueur personnalisée dans admin, vous devez également remplacer les formulaires admin (frustrant, ils ne héritent pas simplement de la longueur du modèle).

 from django.contrib.auth.forms import UserChangeForm, UserCreationForm

UserChangeForm.base_fields['username'].max_length = NEW_USERNAME_LENGTH
UserChangeForm.base_fields['username'].widget.attrs['maxlength'] = NEW_USERNAME_LENGTH
UserChangeForm.base_fields['username'].validators[0].limit_value = NEW_USERNAME_LENGTH
UserChangeForm.base_fields['username'].help_text = UserChangeForm.base_fields['username'].help_text.replace('30', str(NEW_USERNAME_LENGTH))

UserCreationForm.base_fields['username'].max_length = NEW_USERNAME_LENGTH
UserCreationForm.base_fields['username'].widget.attrs['maxlength'] = NEW_USERNAME_LENGTH
UserCreationForm.base_fields['username'].validators[0].limit_value = NEW_USERNAME_LENGTH
UserCreationForm.base_fields['username'].help_text = UserChangeForm.base_fields['username'].help_text.replace('30', str(NEW_USERNAME_LENGTH))
 

2voto

Dmytriy Voloshyn Points 333

Autant que je sache, on peut remplacer le modèle d'utilisateur depuis Django 1.5, ce qui résoudra un problème. Exemple simple ici

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X