'Save() is prohibited to prevent data loss
I'm getting a save() prohibited to prevent data loss due to unsaved related object 'user' in my account views. The line with account = form.save() to be exact. Here's my views, account model, and registration form:
Registration form:
class RegistrationForm(UserCreationForm):
steam_uid = forms.CharField(max_length=17, help_text="Required. Add a valid id")
email = forms.EmailField(max_length=255, help_text="Required. Add a valid email")
class Meta:
model = account
fields = ('steam_uid', 'email', 'username', 'password1', 'password2')
def clean_email(self):
email = self.cleaned_data['email'].lower()
try:
account = account.objects.get(email=email)
except Exception as e:
return email
raise forms.ValidationError(f"Email {email} is already in use.")
def clean_username(self):
username = self.cleaned_data['username']
try:
account = account.objects.get(username=username)
except Exception as e:
return username
raise forms.ValidationError(f"Username {username} is already in use.")
class AccountAuthenticationForm(forms.ModelForm):
password = forms.CharField(label="Password", widget=forms.PasswordInput)
class Meta:
model = account
fields = ("username", "password")
def clean(self):
if self.is_valid():
username = self.cleaned_data['username']
password = self.cleaned_data['password']
if not authenticate(username=username, password=password):
raise forms.ValidationError("Invalid Login")
Register view:
def register_view(request, *args, **kwargs):
user = request.user
if user.is_authenticated:
return HttpResponse("You are already authenticated as " + str(user.email))
context = {}
if request.POST:
form = RegistrationForm(request.POST)
if form.is_valid():
account = form.save()
email = form.cleaned_data.get('email').lower()
raw_password = form.cleaned_data.get('password1')
# Account has already been authenticated at this point. Causes 'AnonymousUser' object has no attribute '_meta' error.
#account = authenticate(email=email, password=raw_password)
login(request, account)
destination = get_redirect_if_exist(request)
if destination:
return redirect(destination)
return redirect('home')
else:
context['registration_form'] = form
else:
form = RegistrationForm()
context['registration_form'] = form
return render(request, 'account/register.html', context)
Account Model:
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, steam_uid, password=None):
if not email:
raise ValueError("Users must have an email address.")
if not username:
raise ValueError("Users must have a username.")
if not steam_uid:
raise ValueError("Users must have a steam id.")
user = self.model(
username = username,
email = email,
steam_uid = steam_uid,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, steam_uid, password):
user = self.create_user(
username = username,
email = email,
steam_uid = steam_uid,
password=password,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
#Profile Image
def get_profile_image_filepath(self):
return f'profile_images/{self.pk}/{"profile_image.png"}'
def get_steam_avatar_filepath(self):
return f'media/profile_images/{self.pk}/{"steam_avatar.png"}'
def get_default_profile_image():
return "defaulties/dummy_image.png"
class account(AbstractBaseUser):
steam_uid = models.CharField(max_length=17, unique=True)
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
personaname = models.CharField(max_length=255, blank=True, null=False)
profileurl = models.CharField(max_length=300, blank=True, null=False)
username = models.CharField(max_length=30, unique = True)
date_joined = models.DateTimeField(verbose_name="date joined", auto_now_add=True)
last_login = models.DateTimeField(verbose_name="last login", auto_now = True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
profile_image = models.ImageField(max_length=255, upload_to=get_profile_image_filepath, null=True, blank=True, default=get_default_profile_image)
hide_email = models.BooleanField(default=True)
objects = MyAccountManager()
__original_steam_uid = None
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email', 'steam_uid']
The issue is within the views where account is equal to form.save(). I've tried setting form.save() to form.save(commit = false) and saving it again but I got the same issue. I'm pretty stomped here.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
