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

Есть ли, что-то не так с выполнением изменяет таблицу на 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 символов, предложенных здесь, но 75 символов, размещает самые нормальные адреса электронной почты. Вопрос нацелен на эту ситуацию, как встречено основанными на электронной почте-авторами приложениями.

65
задан fifi finance 12 December 2016 в 17:03
поделиться

4 ответа

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

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

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

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

Лучше было бы поместить его в модуль моделей фиктивного приложения и поместить это приложение поверх списка / кортежа INSTALLED_APPS (чтобы оно импортировалось раньше, чем что-либо еще). Вот пример того, что вы можете иметь в 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 поля, чтобы отразить новую максимальную длину
  • . Если вы хотите использовать автоматическое администрирование, у вас будет в подкласс 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
78
ответ дан 24 November 2019 в 15:23
поделиться

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

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

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

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

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

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

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

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

1
ответ дан 24 November 2019 в 15:23
поделиться

Если вы просто измените таблицу базы данных, вам все равно придется иметь дело с проверкой 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"))

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

1
ответ дан 24 November 2019 в 15:23
поделиться

Лучшее решение - использовать поле email для email, а имя пользователя - для имени пользователя.

При валидации формы ввода логина, определите, являются ли данные именем пользователя или электронной почтой, и если email, запросите поле email.

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

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

-2
ответ дан 24 November 2019 в 15:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: