Я использую предоставленную Django пользовательскую модель.Все работало нормально, но после одного изменения, когда я попытался сделать поле email
unique
.
my forms.py
:
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
first_name = forms.CharField(max_length=30, required=False, help_text='Optional.')
last_name = forms.CharField(max_length=30, required=False, help_text='Optional.')
email = forms.EmailField(max_length=254, help_text='Required. Inform a valid email address.')
User._meta.get_field('email')._unique = True
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2', )
строку кода, которую я добавил в forms.py
чтобы поле электронной почты unique
было:
User._meta.get_field('email')._unique = True
my views.py
:
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
user.refresh_from_db()
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=4096,
backend=default_backend()
)
public_key = private_key.public_key()
pem_private_key = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
user.profile.public_key = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
raw_password = form.cleaned_data.get('password1').encode()
user.profile.salt = os.urandom(16)
kdf = Scrypt(
salt=user.profile.salt,
length=32,
n=2 ** 20,
r=8,
p=1,
backend=default_backend()
)
key = base64.urlsafe_b64encode(kdf.derive(raw_password))
f = Fernet(key)
user.profile.encrypted_private_key = f.encrypt(pem_private_key)
user.save()
current_site = get_current_site(request)
subject = 'Activate Your MySite Account'
message = render_to_string('accounts/account_activation_email.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),
'token': account_activation_token.make_token(user),
})
user.email_user(subject, message)
return redirect('account_activation_sent')
else:
form = SignUpForm()
return render(request, 'accounts/signup.html', {'form': form})
здесь, где я регистрирую пользователя, я также добавилмодель профиля, в которой я создаю несколько пар ключей для пользователя, все из которых работают как положено.У меня также есть электронное письмо с запросом активации для активации пользователя.
my models.py
:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
email_confirmed = models.BooleanField(default=False)
encrypted_private_key = models.CharField(max_length=500, blank=True)
public_key = models.CharField(max_length=30, blank=True)
salt = models.CharField(max_length=16, blank=True)
@receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
Здесь я создаю профиль пользователя с помощью сигналов.
myHTML-файл:
{% extends 'base.html' %}
{% block content %}
<h2>Sign up</h2>
<form method="post">
{% csrf_token %}
{% for field in form %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit">Sign up</button>
</form>
{% endblock %}
Когда я добавил эту строку кода, чтобы сделать поле email
в auth_user
unique
, мне пришлось сделать makemigrations
, а затем migrate
.Поле email
стало unique
, и я получаю код ошибки при попытке зарегистрироваться на существующее электронное письмо.Но при просмотре базы данных я заметил, что электронная почта сохраняется в столбце last_name
, что действительно странно.
Я попытался переломить ситуацию, удалив эту строку кода и снова применив миграции, но тоже самоепроисходит снова.
Все работало, как и ожидалось, прежде чем я сделал поле электронной почты уникальным.