Как сделать почтовое поле уникальным в модели User от contrib.auth в Django

Операторы переключения с String случаи были реализованы в [1 124] Java SE 7, по крайней мере 16 лет после того, как их сначала требовали. А ясная причина задержки не была обеспечена, но это, вероятно, имело отношение к производительности.

Реализация в JDK 7

опция была теперь реализована в javac с процессом "de-sugaring"; чистый, высокоуровневый синтаксис с помощью String константы в case объявления расширен во время компиляции в более сложный код после шаблона. Получающийся код использует инструкции по JVM, которые всегда существовали.

А switch с String случаи переводится в два переключателя во время компиляции. Первые карты каждая строка к уникальному integer— его положение в исходном переключателе. Это сделано первым включением хэш-кода маркировки. Соответствующий случай if оператор, который тестирует строковое равенство; если существуют коллизии на хеше, тест является расположением каскадом if-else-if. Вторые зеркала переключателя, что в коде первоисточника, но заменах случай маркирует их соответствующими положениями. Этот двухступенчатый процесс облегчает сохранять управление потоком исходного переключателя.

Переключатели в JVM

Для большей технической глубины на switch, можно обратиться к Спецификации JVM, где компиляция операторов переключения описана. Короче говоря существует две различных инструкции по JVM, которые могут использоваться для переключателя, в зависимости от разреженности констант, используемых случаями. Оба зависят от использования целочисленных констант для каждого случая для выполнения эффективно.

, Если константы являются плотными, они используются в качестве индекса (после того, как, вычитая самое низкое значение) в таблицу инструкции pointers— tableswitch инструкция.

, Если константы редки, двоичный поиск корректного случая является performed— lookupswitch инструкция.

В de-sugaring switch на [1 113] объекты, обе инструкции, вероятно, будут использоваться. Эти lookupswitch подходит для первого, включают хэш-коды для нахождения исходного положения случая. Получающийся ординал является естественным пригодным для tableswitch.

Обе инструкции требуют, чтобы целочисленные константы, присвоенные каждому случаю, были отсортированы во время компиляции. Во времени выполнения, в то время как O(1) производительность [1 117] обычно кажется лучше, чем O(log(n)) производительность [1 119], это требует, чтобы некоторый анализ определил, является ли таблица достаточно плотной для выравнивания по ширине space– компромисс времени. Bill Venners записал большая статья , которая касается этого более подробно, наряду со взглядом под капотом на другие инструкции по управлению потоком Java.

, Прежде чем JDK 7

До JDK 7, enum мог приблизиться String - базирующийся переключатель. Это использует помехи valueOf метод, сгенерированный компилятором на каждом enum тип. Например:

Pill p = Pill.valueOf(str);
switch(p) {
  case RED:  pop();  break;
  case BLUE: push(); break;
}

62
задан 3 revs, 2 users 83% 21 July 2009 в 15:55
поделиться

5 ответов

It's amazing, but I found a best solution for me!

django-registration have form with checking uniqueness of email field: RegistrationFormUniqueEmail

example of usage here

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

Внимание: Приведенный ниже код был написан для более старой версии Django (до Custom Были представлены пользовательские модели ). Он содержит состояние гонки и следует использовать только с уровнем изоляции транзакции SERIALIZABLE и транзакции с ограниченным объемом запроса.

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

Если вы когда-либо будете создавать экземпляры User только с формой, вы можете определить настраиваемую ModelForm, которая обеспечивает такое поведение:

from django import forms
from django.contrib.auth.models import User

class UserForm(forms.ModelForm):
    class Meta:
        model = User

    def clean_email(self):
        email = self.cleaned_data.get('email')
        username = self.cleaned_data.get('username')
        if email and User.objects.filter(email=email).exclude(username=username).exists():
            raise forms.ValidationError(u'Email addresses must be unique.')
        return email

Затем просто используйте это форма везде, где вам нужно создать нового пользователя.

Кстати, вы можете использовать Model._meta.get_field ('field_name') для получения полей по имени, а не по позиции. Так, например:

# The following lines are equivalent
User._meta.fields[4]
User._meta.get_field('email')

UPDATE

В документации Django рекомендуется использовать метод clean для всех проверок, охватывающих несколько полей формы, потому что он вызывается после всех .clean и _clean . Это означает, что вы можете (в основном) полагаться на значение поля, присутствующее в cleaned_data изнутри clean .

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

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

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

50
ответ дан 24 November 2019 в 16:38
поделиться

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

-2
ответ дан 24 November 2019 в 16:38
поделиться

Один из возможных способов сделать это - установить обработчик pre-save для объекта User и отклонить сохранение электронного письма, уже существующего в таблице.

2
ответ дан 24 November 2019 в 16:38
поделиться

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

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

(извините, это опубликовано в качестве ответа, но у меня нет прав, чтобы опубликовать его в качестве комментария. Не уверен, что я понимаю логику Stackoverflow по этому поводу.)

0
ответ дан 24 November 2019 в 16:38
поделиться
Другие вопросы по тегам:

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