I'd like each User to be able to create an Account (max of one account each). The user in session won't be able to see the option to create an account unless they are logged in/authenticated. When I log in and click submit on the Create Account form, this error is raised:
'ValueError at /accounts/create/ Cannot assign "<SimpleLazyObject: <User: Jimmy>>": "Account.user" must be a "User" instance.'
My models.py:
from django.db import models
from django.contrib import auth
from django.utils.text import slugify
from django.urls import reverse
from django import template
register = template.Library()
class User(auth.models.User,auth.models.PermissionsMixin):
def __str__(self):
return self.username
class Account(models.Model):
user = models.OneToOneField(User,related_name='customer_account',on_delete=models.CASCADE)
first_name = models.CharField(max_length=30,blank=True)
surname = models.CharField(max_length=30,blank=True)
billing_address = models.TextField(blank=True)
delivery_address = models.TextField(blank=True)
def __str__(self):
return f"Account: {self.user.username}"
def get_absolute_url(self):
return reverse('about',kwargs={'username':self.user.username,
'pk':self.pk})
Views.py:
from django.shortcuts import render
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from braces.views import SelectRelatedMixin
from django.views.generic import (CreateView, UpdateView,
ListView, DetailView,
TemplateView,)
from . import forms
from . import models
from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import redirect
from django.contrib.auth import get_user_model
# User = get_user_model()
class SignUp(CreateView):
form_class = forms.CreateCustomerForm
success_url = reverse_lazy('login')
template_name = 'accounts/signup.html'
class CreateAccount(LoginRequiredMixin,CreateView):
model = models.Account
fields = ['first_name','surname','billing_address','delivery_address']
template_name = 'accounts/create_account.html'
def form_valid(self,form):
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object.save()
return super().form_valid(form)
Forms.py:
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import get_user_model
from . import models
class CreateCustomerForm(UserCreationForm):
class Meta:
model = get_user_model()
fields = ('username','email','password1','password2')
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.fields['username'].label = 'Username'
self.fields['email'].label = "Email Address"
Urls.py:
from django.conf.urls import url
from accounts import views
from django.contrib.auth import views as auth_views
app_name = 'accounts'
urlpatterns = [
url(r'^login/$',auth_views.LoginView.as_view(template_name='accounts/login.html'),name='login'),
url(r'^logout/$',auth_views.LogoutView.as_view(),name='logout'),
url(r'^signup/$',views.SignUp.as_view(),name='signup'),
url(r'^create/$',views.CreateAccount.as_view(),name='create'),
]
Here is where things seem to go wrong according to the Traceback section:
line 39, in form_valid
self.object.user = User …
▼ Local vars
Variable Value
User
<SimpleLazyObject: <User: Jimmy>>
__class__
<class 'accounts.views.CreateAccount'>
form
<AccountForm bound=True, valid=True, fields=(first_name;surname;billing_address;delivery_address)>
self
<accounts.views.CreateAccount object at 0x000001C9E70DBC40>
line 310, in __set__
super().__set__(instance, value) …
▼ Local vars
Variable Value
__class__
<class 'django.db.models.fields.related_descriptors.ForwardOneToOneDescriptor'>
instance
Error in formatting: RelatedObjectDoesNotExist: Account has no user.
self
<django.db.models.fields.related_descriptors.ForwardOneToOneDescriptor object at 0x000001C9E6C72250>
value
<SimpleLazyObject: <User: Jimmy>>
Thanks in advance if you're able to help.