Reputation: 107
I have a registration form which generates in view. Now I need to add some fields from other model. How should I change view to add fields from another model?
Here is my view code:
def register(request):
""" User registration """
if auth.get_user(request).username:
return redirect('/')
context = {}
context.update(csrf(request))
context['form'] = UserCreationForm()
if request.POST:
newuser_form = UserCreationForm(request.POST)
if newuser_form.is_valid():
newuser_form.save()
newuser = auth.authenticate(username=newuser_form.cleaned_data['username'],
password=newuser_form.cleaned_data['password2'])
auth.login(request, newuser)
return redirect('/')
else:
context['form'] = newuser_form
return render(request, 'user_auth/user_auth_register.html', context)
Upvotes: 3
Views: 12097
Reputation: 87
By default the UserCreationForm comes with username, password, first_name, last_name, email.
I wanted to add additional fields of information (easily accomplished after the fact using the ProfileUpdateForm) but I wanted it included in the initial registration form so the user would only have to submit once.
Solution is to use two forms and combine them. The magic trick is to initiate a manual database refresh to access the newly created profile
Reference: https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html
views.py
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
p_reg_form = ProfileRegisterForm(request.POST)
if form.is_valid() and p_reg_form.is_valid():
user = form.save()
user.refresh_from_db() # load the profile instance created by the signal
p_reg_form = ProfileRegisterForm(request.POST, instance=user.profile)
p_reg_form.full_clean()
p_reg_form.save()
messages.success(request, f'Your account has been sent for approval!')
return redirect('login')
else:
form = UserRegisterForm()
p_reg_form = ProfileRegisterForm()
context = {
'form': form,
'p_reg_form': p_reg_form
}
return render(request, 'users/register.html', context)
forms.py
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
class ProfileRegisterForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['city', 'state', 'country', 'referral']
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
confirmed = models.BooleanField("Confirmed", default=False)
city = models.CharField("City", max_length=50, blank=True)
state = models.CharField("State", max_length=50, blank=True)
country = models.CharField("Country", max_length=50, blank=True)
referral = models.CharField("Referral", max_length=50, blank=True)
def __str__(self):
return f'{self.user.username} Profile'
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
Upvotes: 6
Reputation: 13763
Something like this should help you:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class UserCreateForm(UserCreationForm):
extra_field = forms.CharField(required=True)
class Meta:
model = User
fields = ("username", "extra_field", "password1", "password2")
def save(self, commit=True):
user = super(UserCreateForm, self).save(commit=False)
user.extra_field = self.cleaned_data["extra_field"]
if commit:
user.save()
return user
Basically, extending UserCreationForm
and adding an extra field. Also, save it in the save()
method.
Hope it helps.
Upvotes: 8