A username
требуется для объекта User.Но вы также можете сделать это username
их email
, так что это не проблема (по крайней мере, в django 2.x, не уверен насчет 1.x) .Вы не описали, для чего предназначалось создаваемое вами приложение, его назначение и т. Д., , поэтому прежде чем переходить к коду, прочитайте следующие предупреждения и продумайте, почему я даю вам лучшееoption.
Это очень плохая идея, чтобы заставить человека иметь имя пользователя равное его электронной почте, , потому что в будущем вы можете захотеть добавить некоторые другие функции.
Например: Может быть, вы захотите создать доску объявлений, чтобы люди могли общаться друг с другом.Но из-за плохого планирования с самого начала все видели друг друга по электронной почте.Технически, вы можете присвоить им всем набор случайных имен пользователей, которые они не придумали, но это не очень хорошая идея, потому что они с меньшей вероятностью запомнят это, и им это может не понравиться.Единственное хорошее имя, такое как sPaRkLe_DaNcEr12
или Poothtaste
, предназначено для того, чтобы заставить людей бросать ярость в видеоиграх.
Так что, если вы хотите, чтобы пользователи в будущем могли общаться с нимидруг другу, было бы лучше показывать свое имя пользователя другим пользователям, но ПОЗВОЛИТЬ людям входить в систему, используя свою электронную почту или номер телефона, если они хотят. Таким образом, теперь они могут войти в систему со своими * 1026.* и они должны помнить только один из них.Я покажу вам, как скоро.
Некоторые недостатки этого: Это делает больше запросов к вашей базе данных, что может замедлить работу, если у вас есть тонны пользователей, но это ваш звонок.Лично я говорю, что оно того стоит, потому что оно ничтожно и проще для пользователей, и именно им вы должны угодить.Так плати за более быстрый сервер или нет ???В конечном счете, вы всегда должны разрабатывать так, чтобы было как можно меньше запросов, при этом кэшируя определенные страницы, которые перегружены базой данных, чтобы не выполнять одно и то же X раз.
Давайте начнем:
Помните, что ниже приведен пример того, что я бы сделал для django 2.x, с лучшей функциональностью, чем вы просите .Если вы используете 1.x, просто используйте url()
вместо path()
и любые другие требования.
Предположим, у нас есть приложение под названием accounts_app
.
Также предположим, чтомы помещаем path('accounts/', include('accounts_app.urls')),
в наш уровень проекта urls.py
.
Я также собираюсь предположить, что вы знаете, как использовать шаблоны ... Теперь создайте urls.py
внутри этого приложения:
accounts_app / urls.py:
app_name = 'accounts_app'
urlpatterns = [
...
path('signup/', views.signup, name='signup'),
]
accounts_app / models.py:
Приведенный ниже атрибут user
позволяет вамРасширьте модель User
, чтобы вы могли иметь их phone_number
.В этом примере я допустил, чтобы это было пустым в случае, если они не хотят давать это.Но если бы они это сделали, вы бы сделали для этого отдельное представление. Чтобы сделать все это намного проще, я не буду это включать и рассказывать вам, какперезаписать всю модель пользователя.Я только покажу вам, как войти по электронной почте с обычной моделью User
.После этого делать это с номером телефона совсем не сложно.Напоминание о том, что вам понадобится, находится в самом конце этого поста.
class ExtendedUserExample(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
phone_number = models.IntegerField(blank=True)
settings.py .... ПРИМЕЧАНИЕ, ЧТО ЭТО В ПАПКЕ УРОВНЯ ПРОЕКТА
Порядок этих бэкэндов имеет значение.Всегда сначала делайте ModelBackend, иначе он сломается.
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'accounts_app.authentication.EmailAuthBackend', # to be able to login with email, described next
]
accounts_app / authentication.py:
Это пример того, как можно войти в систему по электронной почте.Если вы хотите, чтобы кто-то тоже входил по номеру телефона, принцип тот же, но в этом файле вам также необходимо импортировать модель ExtendedUserExample
, указанную выше, добавьте ее к вышеуказанным настройкам AUTHENTICATION_BACKENDS
внизу.и создайте новый класс для PhoneAuthBackend
, который ищет ExtendedUserExample
для phone_number
.Опять же, чтобы упростить эту задачу, я не полностью перезаписываю модель User
, а лишь расширяю ее, поэтому, если пользователь создал учетную запись и хотел войти в систему по номеру телефона позже, ему пришлось бы зарегистрироваться сСначала введите имя пользователя и адрес электронной почты, а затем они могут добавить номер телефона (в этом примере вам потребуется другой вид для этого).
Поэтому сначала попробуйте этот пример электронной почты, пока не получитеСуть этого.Вам также не нужно импортировать этот файл куда-либо еще, потому что об этом позаботится файл settings.py
.
Вот что происходит: В вашем шаблоне для входа в систему он сначала выполнит поискдля поля username
внутри вашей модели User
, поскольку в вашем файле settings.py
есть переменная AUTHENTICATION_BACKENDS
для первой проверки ModelBackend
.
Но, скажем, пользователь ввел username
в качествеaaa@aaa.com
.Теперь, так как вы не позволили никому зарегистрироваться с электронной почтой в качестве имени пользователя, когда aaa@aaa.com
не найден как username
в модели User
, ваш файл настроек теперь говорит, что нужно пойти и проверить то же самое User
возражать во второй раз, но вместо этого искать их ввод по полю / столбцу email
.Если они введены в этот столбец, authenticate()
регистрирует их по электронной почте, если пароль правильный.
from django.contrib.auth.models import User
class EmailAuthBackend(object):
""" Authenticate using an email address """
def authenticate(self, request, username=None, password=None):
try:
user = User.objects.get(email=username) # gets the email by the 'username' they entered
if user.check_password(password):
return user
return None
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
acounts_app / views.py:
Я предполагаю, что вы знаете, как сделать формы Django.Если нет, проверьте здесь формы моделей.
from .forms import ExtendedUserForm
def signup(request):
form = ExtendedUserForm(request.POST or None)
if request.method == 'POST':
if request.POST['password1'] == request.POST['password2']:
potential_user = request.POST.get('username', False).lower()
try:
user = User.objects.get(username=potential_user)
return render(request, 'accounts_app/signup.html', {'error': 'Username has already been taken. Please try another'})
except User.DoesNotExist:
if form.is_valid():
new_user = User.objects.create_user(username=potential_user, email=request.POST['email'], password=request.POST['password1'])
# backend argument required cause we are making the ability to LOGIN by email.
# Remember, I only extended the User model.
auth.login(request, new_user, backend='django.contrib.auth.backends.ModelBackend')
return redirect('some_app:some_view')
else:
return render(request, 'accounts_app/signup.html', {'error': "Password's must match."})
return render(request, 'accounts_app/signup.html', {'form': form})
Теперь, когда ваш логин по электронной почте должен работать, несложно следовать этим принципам при созданиитакая же возможность для входа по телефону.Если вы продолжите этот пример, вам нужно будет создать новое представление, чтобы сохранить номер телефона в ExtendedUserExample.phone_number
.После этого добавьте еще одну строку внизу AUTHENTICATION_BACKENDS
, напишите новый класс в authentication.py
, и вы будете настроены ... Если у вас есть <input type="text" name="username" required>
, когда они используют ваш вид входа в систему.