I have a Profile model:
class Profile(models.Model):
id = models.BigAutoField(primary_key=True)
#id = models.CharField(primary_key=True, default=shortuuid.uuid, max_length=26)
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
account = models.ForeignKey('Account', verbose_name=_('account'), on_delete=models.CASCADE)
home_phone = PhoneNumberField(_('Home phone'), max_length=30, null=True, blank=True, help_text=_('If outside the UK include country code (eg: "+39", "+353", "+33"…)'))
work_phone = PhoneNumberField(_('Work phone'), max_length=30, null=True, blank=True, help_text=_('If outside the UK include country code (eg: "+39", "+353", "+33"…)'))
mobile_phone = PhoneNumberField(_('Mobile phone'), max_length=30, null=True, blank=True, help_text=_('If outside the UK include country code (eg: "+39", "+353", "+33"…)'))
receive_news = models.BooleanField(_('Receive news'), default=True, db_index=True)
createdate = models.DateTimeField(auto_now_add=True, db_index=True)
moddate = models.DateTimeField(auto_now=True, db_index=True)
@staticmethod
def get_or_create_for_user(user):
if hasattr(user, 'profile'):
return user.profile
else:
return Profile.objects.create(user=user)
And in settings.py:
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
)
Which is what I think links the Profile
to the User
.
I put together a simple view:
class ControlProfileCreateView(CreateView):
model = get_user_model()
template_name = 'manageit/control/profile_edit.html'
form_class = ControlProfileForm
success_url = reverse_lazy('admin-control')
and form:
class ControlProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = (
'home_phone',
'work_phone',
'mobile_phone',
'receive_news'
)
I can get an empty form in a browser, but when I save the form I get an error that the Column 'user_id' cannot be null
. I know this is a MySQL error, and I understand why (because the user
field in Profile
needs an id to link it to auth_user
table).
No real idea how to get around that.
I tried searching for queires others had posted about this subject, and found some notes on allauth, which used this form:
class ControlProfileForm(forms.Form):
model = get_user_model()
first_name = forms.CharField(max_length=30, label='First name')
last_name = forms.CharField(max_length=30, label='Last name')
email = forms.CharField(max_length=30, label='E-mail')
#home_phone = forms.CharField(max_length=20, label='Home phone')
#work_phone = forms.CharField(max_length=20, label='Work phone')
#mobile_phone = forms.CharField(max_length=20, label='Mobile phone')
def signup(self, request, user):
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.email = self.cleaned_data['email']
# Replace 'profile' below with the related_name on the OneToOneField linking back to the User model
#up = user.profile
#up.home_phone = self.cleaned_data['home_phone']
user.save()
#up.save()
But on calling the form in a browser I get an error:
__init__() got an unexpected keyword argument 'instance'
Which is buried in django/views/generic/edit.py
I want the admin user to be able to create the Profile
/auth_user
rows, on a form, but not in the Django Admin interface.
Sorry, this keeps saving before I finish!