Может ли auth_user.username django быть varchar (75)? Как это можно сделать?

Есть ли что-то не так с работой таблицы alter на auth_user чтобы сделать username varchar(75) чтобы оно могло соответствовать электронной почте? Что это может сломать?

Если вы должны были изменить auth_user.username чтобы быть varchar(75) где вам нужно было бы изменить django? Это просто вопрос изменения 30 – 75 в исходном коде?

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

Или есть другая проверка в этой области, которая должна быть изменена или какие-либо другие последствия для этого?

См. Обсуждение комментария с bartek ниже относительно причины для этого.

Изменить : Оглядываясь назад на это через много месяцев. Для тех, кто не знает предпосылки: в некоторых приложениях нет требования или желания использовать имя пользователя, они используют только электронную почту для регистрации и авторизации. К сожалению, в django auth.contrib требуется имя пользователя. Вы можете начать отправлять электронные письма в поле имени пользователя, но поле составляет всего 30 символов, а электронные письма могут быть длинными в реальном мире. Потенциально даже дольше, чем 75 char, предложенный здесь, но 75 char вмещают самые разумные адреса электронной почты. Вопрос направлен на эту ситуацию, поскольку она встречается приложениями на основе электронной почты.

Есть способ достичь этого, не касаясь основной модели и без наследования, но это определенно хакерский, и я буду использовать его с особой осторожностью.

Если вы посмотрите на док- class_prepared Django на сигналы , вы увидите, что один из них называется class_prepared , который в основном отправляется после того, как какой-либо фактический class модели был создан метаclassом. Этот момент – ваш последний шанс модифицировать любую модель до того, как ModelAdmin какая-либо магия (например: ModelForm , ModelAdmin , syncdb и т. Д.).

Таким образом, план прост, вы просто регистрируете этот сигнал с помощью обработчика, который будет определять, когда он вызывается для модели User , а затем измените свойство max_length поля имени username .

Теперь вопрос в том, где должен жить этот код? Он должен быть выполнен до загрузки модели User , так что часто это означает очень рано . К сожалению, вы не можете (django 1.1.1 , не проверять с другой версией) поместить это в settings потому что импорт signals там сломается.

Лучшим вариантом было бы разместить его в модуле моделей фиктивных приложений и разместить это приложение поверх списка INSTALLED_APPS / tuple (чтобы он импортировался раньше всего). Вот пример того, что вы можете иметь в 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) 

Это сделает трюк.

Несколько примечаний:

  • Возможно, вы захотите изменить также help_text поля, чтобы отразить новую максимальную длину
  • Если вы хотите использовать автоматический администратор, вам придется подclassифицировать UserChangeForm , UserCreationForm и AuthenticationForm поскольку максимальная длина не выводится из поля модели, а непосредственно в декларации поля формы.

Если вы используете Юг , вы можете создать следующую миграцию, чтобы изменить столбец в базовой базе данных:

 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 

Основываясь на замечательном комбинированном ответе Клемента и Мэтта Миллера выше, я собрал быстрое приложение, которое его реализует. Пип-установка, миграция и переход. Поставил бы это как комментарий, но еще не имеет пароля!

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

EDIT 2014-12-08

Вышеупомянутый модуль теперь устарел в пользу https://github.com/madssj/django-longer-username-and-email

Обновленное решение для версии Django 1.3 (без изменения manage.py):

Создайте новое django-приложение:

 monkey_patch/ __init__.py models.py 

Установите его как сначала: (settings.py)

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

Вот модели.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() 

Приведенные выше решения, похоже, обновляют длину модели. Однако, чтобы отразить вашу пользовательскую длину в admin, вам также необходимо переопределить формы администратора (к сожалению, они не просто наследуют длину от модели).

 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)) 

Насколько я знаю, можно переопределить модель пользователя с Django 1.5, которая решит проблему. Простой пример здесь

Если вы просто измените таблицу базы данных, вам все равно придется иметь дело с проверкой Django, поэтому она не позволит вам сделать более 30 символов. Кроме того, имя пользователя проверяется так, что он не может иметь специальные символы, такие как @ поэтому простое изменение длины поля не будет работать. Мой плохой, похоже, что он справляется с этим. Вот имя пользователя из models.py в django.contrib.auth:

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

Создание авторизации электронной почты не сложно. Вот супер простой сервер электронной почты, который вы можете использовать. Вы должны сделать это после добавления дополнительной проверки, чтобы убедиться, что адрес электронной почты уникален, и все готово. Это просто.

Да, это может быть сделано. По крайней мере, я думаю, что это должно сработать; Я закончил замену всей модели auth, поэтому я готов исправляться, если это не сработает …

Если у вас нет записей пользователей, о которых вы заботитесь:

  1. удалить таблицу auth_user
  2. смените имя пользователя на max_length = 75 в модели
  3. SyncDB

Если у вас есть записи пользователя, которые вам нужно сохранить, это сложнее, поскольку вам нужно каким-то образом их перенести. Самый простой – это резервное копирование и восстановление данных из старой в новую таблицу, например:

  1. резервное копирование данных таблицы пользователя
  2. отбросить стол
  3. SyncDB
  4. повторно импортировать данные пользователя в новую таблицу; чтобы восстановить исходные значения id

В качестве альтернативы, используя свой безумный навык python-django, скопируйте экземпляры пользовательской модели от старого к новому и замените:

  1. создайте свою собственную модель и временно оставите ее рядом с моделью по умолчанию
  2. написать сценарий, который копирует экземпляры из модели по умолчанию в новую модель
  3. замените модель по умолчанию своей пользовательской

Последнее не так сложно, как кажется, но, очевидно, требует немного больше работы.

По сути, проблема в том, что некоторые люди хотят использовать адрес электронной почты как уникальный идентификатор, в то время как система аутентификации пользователя в Django требует уникального имени пользователя не более 30 символов. Возможно, это изменится в будущем, но в этом случае Django 1.3, как я пишу.

Мы знаем, что 30 символов слишком короткие для многих адресов электронной почты; даже 75 символов недостаточно для представления некоторых адресов электронной почты, как объясняется в разделе «Какая оптимальная длина для адреса электронной почты в базе данных? ,

Мне нравятся простые решения, поэтому я рекомендую hashировать адрес электронной почты в имя пользователя, которое соответствует ограничениям для имен пользователей в Django. Согласно аутентификации пользователя в Django , имя пользователя должно быть не более 30 символов, состоящее из буквенно-цифровых символов и _, @, +,. а также -. Таким образом, если мы используем кодировку base-64 с тщательной подстановкой специальных символов, у нас есть до 180 бит. Таким образом, мы можем использовать 160-битную hash-функцию, такую ​​как SHA-1, следующим образом:

 import hashlib import base64 def hash_user(email_address): """Create a username from an email address""" hash = hashlib.sha1(email_address).digest() return base64.b64encode(hash, '_.').replace('=', '') 

Короче говоря, эта функция связывает имя пользователя для любого адреса электронной почты. Я знаю, что крошечная вероятность столкновения в hash-функции, но это не должно быть проблемой в большинстве приложений.

Просто добавив ниже код внизу файла settings.py

 from django.contrib.auth.models import User User._meta.get_field("username").max_length = 75 

C: … \ venv \ Lib \ сайт-пакеты \ Джанго \ вно \ Auth \ models.py

first_name = models.CharField (_ (‘first name’), max_length = 30, blank = True)

изменить на

first_name = models.CharField (_ (‘first name’), max_length = 75, blank = True)

спасти

и изменение в базе данных

Я использую django 1.4.3, что делает его довольно легким, и мне не нужно было что-то менять в моем коде после реализации того, что я хотел использовать длинные адреса электронной почты в качестве имен пользователей.

Если у вас есть прямой доступ к базе данных, измените ее там на количество символов, которое вы хотели бы, в моем случае 100 символов.

В вашей модели приложения (myapp / models.py) добавьте следующее

 from django.contrib.auth.models import User class UserProfile(models.Model): # This field is required. User._meta.get_field("username").max_length = 100 user = models.OneToOneField(User) 

Затем в вашем файле settings.py указывается модель:

 AUTH_USER_MODEL = 'myapp.UserProfile' 

Лучшее решение – использовать поле электронной почты для электронной почты и имя пользователя для имени пользователя.

В подтверждении формы входа в систему, найдите, являются ли данные именем пользователя или электронной почтой, а также электронной почтой, введите запрос в поле электронной почты.

Это требует, чтобы обезьяна исправляла contrib.auth.forms.login_form которая представляет собой несколько строк в соответствующем представлении.

И это намного лучше, чем пытаться изменить модели и таблицы базы данных.

Если вы используете venv (виртуальная среда), самое простое решение, вероятно, просто обновляет основной код напрямую, то есть открывает следующие два файла: – – venv / lib / python2.7 / sites-packages / django / contrib / auth / model .py – venv / lib / python2.7 / sites-packages / django / contrib / auth / forms.py Найдите все поля имени пользователя и измените max_length от 30 до 100. Это безопасно, поскольку вы уже используете venv, чтобы выиграть ‘ t влияет на любой другой проект Django.

  • Как выразить отношения «один-ко-многим» в Django
  • Django: реализация JOIN с использованием Django ORM?
  • В методе custom save () модели django, как вы должны идентифицировать новый объект?
  • Поле пароля в модели Django
  • Переопределить запрос по умолчанию в Django admin
  • Пользовательские менеджеры Django - как мне вернуть только объекты, созданные зарегистрированным пользователем?
  • Django: заполнение идентификатора пользователя при сохранении модели
  • Как я могу использовать два внешних ключа для одной модели в Django?
  • Привязка к истории моделей Django Admin
  • Пользовательский QuerySet и Менеджер без нарушения DRY?
  • Профиль пользователя Django
  • Interesting Posts

    Создание символических ссылок на сетевом диске

    Понимание dispatch_async

    Нужно ли форматировать отрицательные числа красным цветом в таблице в Powerpoint 2010?

    Можно ли использовать -1 для установки всех битов в true?

    Есть ли способ заставить ПК выглядеть как USB-накопитель на устройстве, которое считывает содержимое с USB-накопителя?

    Как очистить или удалить параметры политики групповой политики домена после выхода из домена

    Как запустить приложение Android из командной строки?

    Как урезать миллисекунды с .NET DateTime

    Задайте вывод команды как переменной (с помощью труб)

    Получение всех типов в пространстве имен посредством отражения

    Как проверить, действительно ли значение enum?

    Завершение табуляции для аргументов команды не работает в Cygwin из-за суффикса `.exe`

    Можно ли открыть 2 PDF-документа в Windows 8?

    Съемка с камеры без предварительного просмотра

    Скрытые особенности VBA

    Давайте будем гением компьютера.