Пользовательская модель пользователя в django. Ошибка ограничения UNIQUE: users_user.username - PullRequest
1 голос
/ 07 мая 2020

Я пытаюсь создать индивидуальную регистрационную форму. Основная идея заключается в том, что пользователи должны использовать электронную почту в качестве метода входа в систему и иметь возможность устанавливать имя пользователя в профиле (поэтому я не хочу переопределять поле имени пользователя). Проблема со встроенной моделью django User заключается в том, что требуется поле имени пользователя, поэтому я создал свою собственную модель на основе AbstractUser. Теперь, когда я пытаюсь зарегистрировать нового пользователя, я получаю сообщение «Не удалось выполнить ограничение UNIQUE: users_user.username».

models.py

from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass

forms.py

from django import forms
from .models import User

class RegisterForm(forms.ModelForm):
    username = forms.CharField(max_length=100, required=False)
    email = forms.EmailField(label='', max_length=100, widget=forms.TextInput(attrs={'placeholder': 'email@example.com'}))
    password = forms.CharField(label='', max_length=100, widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))

    class Meta:
        model = User
        fields = ['username', 'email', 'password']

views.py

from django.shortcuts import render, redirect
from django.contrib import messages

from .forms import RegisterForm


def register(request):
    if request.method == 'POST':
        form = RegisterForm(request.POST)
        if form.is_valid(): 
            form.save()
            return redirect('trade')

    else:
        form = RegisterForm()
        return render(request, 'users/register.html', {'form': form})

AUTH_USER_MODEL = 'users.User' установлен

Я попытался установить email unique = True в models.py

from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    email = models.EmailField(unique=True)

Теперь я получаю: «Представление users.views.register не вернуло объект HttpResponse. Вместо этого он возвратил None».

Имейте в виду, что это мой первый django проект :) Помощь приложено!

РЕДАКТИРОВАТЬ с решением:

Ну, я решил это. Все ответы в django документации (кто бы учил). Проблема в том, что если вы новичок, как я, для python и django, чтение документации по пользовательской модели пользователя может быть очень утомительным. Основная цель заключалась в том, чтобы установить электронную почту в качестве метода входа в систему. Для этого вам нужно установить USERNAME_FIELD = 'email' в вашей модели. И чтобы иметь возможность сделать это, вы должны создать свою модель, основанную не на AbstractUser, а на AbstractBaseUser (https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#specifying -a-custom-user-model ) и переписать способ создания пользователей. Мне это показалось довольно сложным, но django имеет очень хороший пример того, как это сделать, прямо в конце документации (https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#a -full-example ). Я просто скопировал код, заменил date_of_birth на username и получил именно то, что хотел, плюс немного понимания того, как все работает.

1 Ответ

0 голосов
/ 07 мая 2020

Что касается ошибки "The view users.views.register didn't return an HttpResponse object. It returned None instead", это происходит потому, что register не возвращает что-то во всех потоках. В случае, когда запрос POST, первый оператор if истинен, так что это ветвь, в которой мы находимся. Если форма действительна, все в порядке, но если это не так, ничего не возвращается. Мы не вводим часть else, потому что это происходит только тогда, когда запрос не POST, вы можете исправить это, выполнив следующие действия:

def register(request):
    if request.method == 'POST':
        form = RegisterForm(request.POST)
        if form.is_valid(): 
            form.save()
            return redirect('trade')

    else:
        form = RegisterForm()
    return render(request, 'users/register.html', {'form': form})

Таким образом, во всех ситуациях вы что-то возвращаете.

По поводу исходной ошибки. Поскольку вы наследуете от AbstractUser, вы наследуете поле username и все связанные с ним поведения. В частности, он по-прежнему должен быть уникальным. Вот как это определено в AbstractUser:

    username = models.CharField(
        _('username'),
        max_length=150,
        unique=True,
        help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
        validators=[username_validator],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
    )

Это вызовет у вас проблемы, если вы отправляете пустые значения в свое имя пользователя. Ваша форма позволит это, но не будет разрешено на уровне базы данных. Там я бы перезаписал имя пользователя, просто добавил что-то вроде этого:

    username = models.CharField(
        max_length=150,
        blank=True,
    )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...