I am curious to see what the line model = User does in my forms.py so I decided to comment it out. The result was this error:
ModelForm has no model class specified.
and it is highlighted on line 45 of views.py
args['form'] = MyRegistrationForm()
I'm still not quite sure how the model = User plays a roll in my custom user registration form. (I've been following a tutorial). I was wondering if someone could briefly explain to me this whole process and why model = User is needed
My guess is that model is now a User object. Also args['form'] = MyRegistrationForm() needs to be a model object or else the code will crash. This is as far as my assumptions go.
My views.py:
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.core.context_processors import csrf
from forms import MyRegistrationForm
def register_user(request):
if request.method == 'POST':
form = MyRegistrationForm(request.POST) # create form object
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/register_success')
args = {}
args.update(csrf(request))
args['form'] = MyRegistrationForm()
print args
return render(request, 'register.html', args)
my forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class MyRegistrationForm(UserCreationForm):
email = forms.EmailField(required = True)
first_name = forms.CharField(required = False)
last_name = forms.CharField(required = False)
birthday = forms.DateField(required = False)
class Meta:
#model = User
fields = ('email', 'username', 'password1', 'password2', 'last_name', 'first_name', 'birthday') # set up ordering
def save(self,commit = True):
user = super(MyRegistrationForm, self).save(commit = False)
user.email = self.cleaned_data['email']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.birthday = self.cleaned_data['birthday']
if commit:
user.save()
return user
I'm still not quite sure how the model = User plays a roll in my
custom user registration form.
Your form inherit from django.contrib.auth.forms.UserCreationForm which is a ModelForm.
I was wondering if someone could briefly explain to me this whole
process and why model = User is needed
ModelForms are documented here : https://docs.djangoproject.com/en/1.5/topics/forms/modelforms/
As a side note, if you had inherited your form's Meta from UserCreationForm.Meta you wouldn't need to specify the model once again.
My guess is that model is now a User object.
User is a class.
Also args['form'] = MyRegistrationForm() needs to be a model object
or else the code will crash. This is as far as my assumptions go.
Don't assume: read the doc, then read the code (remember, it's open source software).
Related
I apologize if my mistake is incredibly simple but I am completely new to Django. Currently, my models.py currently contains 2 types of profiles extending off of the default Django User model:
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
first_name = models.CharField(max_length = 50)
last_name = models.CharField(max_length = 50)
def __str__(self):
return self.user.username
class PCOProfile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
org_name = models.CharField(max_length = 100)
org_phone = models.CharField(max_length = 20)
is_active = models.BooleanField(default = False)
def __str__(self):
return f"{self.user.username} | {self.org_name}"
I have a views.py file which contains 2 functions, one called register and another register-pco that collects base user information, as well as information related to only one of of these models as a form on the same page which will be submitted at the same time as the base user information:
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import UserRegistrationForm, UserProfileForm, PCOProfileForm
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
profile_form = UserProfileForm(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
# Hooking up user_profile model to django default user model
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
username = user_form.cleaned_data.get('username')
messages.success(request, f'Your account has been created. You can now login as {username}!')
return redirect('login')
else:
user_form = UserRegistrationForm()
profile_form = UserProfileForm()
context = {'user_form':user_form, 'profile_form':profile_form, 'title':'Register'}
return render(request, 'users/register.html', context)
def register_pco(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
pco_profile_form = PCOProfileForm(request.POST)
if user_form.is_valid() and pco_profile_form.is_valid():
user = user_form.save()
# Hooking up pco model to django default user model
pco_profile = PCOProfileForm.save(commit=False)
pco_profile.user = user
pco_profile.save()
username = user_form.cleaned_data.get('username')
messages.success(request, f'Your account has been created. You can now login as {username}!')
return redirect('login')
else:
user_form = UserRegistrationForm()
pco_profile_form = PCOProfileForm()
context = {'user_form':user_form, 'pco_profile_form':pco_profile_form, 'title':'Register'}
return render(request, 'users/register.html', context)
#login_required
def profile(request):
return render(request, 'users/profile.html')
The problem I am currently experiencing is that when I submit the registration form on the register-pco path, it fails to instantiate a PCOprofile object while the base user information gets saved in the database just fine. The end result is a TypeError at /register-pco/ save() missing 1 required positional argument: 'self'. Additionally, the regular register path works just as expected, adding a user in the database with a corresponding profile.
For reference, I was following this guide to try and get user types setup in a simple manner (via 1-1 fields) but it seems as if there might be something wrong with the way I am making the forms since the models themselves work (I tested them in the django shell).
Here is the forms.py file without the imports:
class UserRegistrationForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username','email','password1','password2']
class UserProfileForm(ModelForm):
class Meta:
model = UserProfile
fields = ['first_name','last_name']
class PCOProfileForm(ModelForm):
class Meta:
model = PCOProfile
fields = ['org_name','org_phone']
You're not calling save() on the instance of form you created, but on the form class. So instead of this:
# Hooking up pco model to django default user model
pco_profile = PCOProfileForm.save(commit=False)
you should call it with the form instance you assigned into variable pco_profile_form a few lines above:
# Hooking up pco model to django default user model
pco_profile = pco_profile_form.save(commit=False)
I was trying to register a new user through the frontend with the help of django but i saw quite a few tutorials use UserCreationForm but for my case it does't seem to work.
views.py
def registerUser(request) :
form = RegisterForm()
context = {'form':form}
if request.method == 'POST' :
form = RegisterForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'User Created succesfully')
print('user Created')
return redirect('users:login')
else :
print('Not valid')
return render(request, 'register.html', context)
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class RegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ["username", "email", "password1", "password2"]
My is_valid() function is giving me that the request.POST isn't valid.
Look at Django's UserCreationForm source code.
# default
class Meta:
model = User
fields = ("username",)
field_classes = {'username': UsernameField}
By implementing your own fields, you are potentially destroying Django's default form. All I can see, the error lies as you did not set field_classes for username. Try changing that.
In Your forms.py try this,
class UserCreateForm(UserCreationForm):
fields = ('username', 'email', 'password1', 'password2', 'first_name', 'last_name')
model = YOUR_MODEL_THAT_YOU_HAVE_CREATED()
class Meta:
# Some Custom Options...
I'm trying to add data from UserCreationForm extra fields to database, i want to add multiple fields to UserCreationForm and save it to database. I saw other examples from topics here in stackoverflow, but it doesn't work.
Here is a example of my code:
( fields: "agree_terms" or "price" could be anything else)
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class UserRegisterForm(UserCreationForm):
email = forms.EmailField(widget = forms.EmailInput(attrs=
{'placeholder':'Email'}))
agree_terms = forms.BooleanField()
price = forms.DecimalField(decimal_places=2, max_digits=10000)
class Meta(UserCreationForm.Meta):
model = User
fields = UserCreationForm.Meta.fields + ('username', 'password1',
'email','password2','agree_terms','price')
views.py
#csrf_protect
def registers(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
print(form)
print(form.is_valid())
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request,'Conta criada {}'.format(username))
return redirect('login')
else:
form = UserRegisterForm()
return render(request,'header-login.html',{'form':form})
Did you also changed your User model to support those fields? You'd need to add them to the model/table as well.
Although, I wouldn't recommend piling up so much extra data directly on the User model.
First attempt at trying to create a student user by extending the User model.
Issue: Upon clicking register btn i.e.Login (btn) instead of
redirecting to home it shows the following: NameError at /register/
...name 'user' is not defined
File "E:\ifb299\tutorial2\accounts\views.py", line 33, in register
Students.objects.create(user=user) NameError: name 'user' is not defined [25/Mar/2018 14:38:07] "POST /register/ HTTP/1.1" 500 67801
Not really sure what I'm doing wrong, why is Students.objects.create(user=user) wrong and how do i fix it, please?
views.py
from django.shortcuts import render
from django.shortcuts import redirect
from accounts.forms import RegistrationForm, EditProfileForm
from django.contrib.auth.models import User
from accounts.models import Students
from django.contrib.auth.forms import UserChangeForm
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
def home(request):
return render(request, 'accounts/home.html')
def login_redirect(request):
return redirect('/login/')
def register(request):
# Once register page loads, either it will send to the server POST data (if the form is submitted), else if it don't send post data create a user form to register
if request.method == "POST":
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
Students.objects.create(user=user)
return redirect('../home/')
else:
# Create the django default user form and send it as a dictionary in args to the reg_form.html page.
form = RegistrationForm()
args = {'form': form}
return render(request, 'accounts/reg_form.html', args)
#login_required
def view_profile(request):
args = {'user': request.user}
return render(request, 'accounts/profile.html', args)
#login_required
def edit_profile(request):
# Handle post request - if the user submits a form change form details and pass the intance user
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect('../profile')
# Handles the get request - if no post info is submitted then get the form and display it on the edit profile page.
else:
form = EditProfileForm(instance=request.user)
args = {'form': form}
return render(request, 'accounts/profile_edit.html', args)
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.db.models.signals import *
from django.conf import settings
class Students(AbstractUser):
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
forms.py
from django import forms
from django.contrib.auth.models import User
from .models import *
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from betterforms.multiform import MultiModelForm
from django.contrib.auth.forms import UserCreationForm
# Create a custom form that inherites form UserCreationForm (adding our own fields to save i db)
# Inheriting form in the paramters ()
class RegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = Students
fields = (
'username',
'first_name',
'last_name',
'email',
'password1',
'password2',
'bio',
'location',
'birth_date',
)
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
# Inherits from UserChangeForm class - we keep everything i.e. methods, functionality same but change the things we want to show - connected to the User model
class EditProfileForm(UserChangeForm):
class Meta:
model = User
# Create fields variable get has all the fields we want to show
fields = (
'email',
'first_name',
'last_name',
'password'
)
first, you did not save the return value of form.save() to the variable user.
second, there is no field user your model Student.
I am trying to make a user registration form in django.
I browsed through many links but I am still confused. I am making some sill mistake please point it out.
here is my code:
models.py
from django.db import models
from django.db.models.signals import post_save
from django.contrib.auth.models import User
class UserProfile(models.Model):
mobile = models.CharField(max_length = 20, null=False)
address = models.CharField(max_length = 200)
user = models.OneToOneField(User, unique=True)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class CustomerRegistrationForm(UserCreationForm):
mobile = forms.CharField(max_length = 20)
address = forms.CharField(max_length = 200)
class Meta:
model = User
fields = ('username','email','mobile','address','password1','password2')
view.py
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.template import RequestContext
from django.core.context_processors import csrf
from neededform.forms import CustomerRegistrationForm
def register(request):
print "I am in register function"
if request.method == 'POST':
if request.method == 'POST':
form = CustomerRegistrationForm(request.POST)
if form.is_valid():
f = form.save()
return HttpResponseRedirect('/registered/')
else:
args = {}
args.update(csrf(request))
args['form'] = CustomerRegistrationForm()
return render_to_response('User_Registration.html', args ,context_instance = RequestContext(request))
what I am thinking is that when I do a form.save() in views.py, django should create the user in auth_user table and must insert the values (i.e mobile and address ) in the UserProfile table also.
but what happening is that it is inserting data in auth_user table correctly but in the UserProfile table only id and user_id coloumns are filled, mobile and address both remains empty.
What am I doing wrong ? What else must be done ?
Thank you.
Take a look at the following:
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
You create a UserProfile object which only has its user attribute set!
I don't think that using signal is the best approach to your problem since it's not easy to pass the mobile and address from your form to the Profile creation point. Instead you can override the save() method of your CustomerRegistrationForm where you'd first save the user and then create the profile. Something like this:
class CustomerRegistrationForm(UserCreationForm):
# rest code ommited
def save(self, commit=True):
user = super(CustomerRegistrationForm, self).save()
p = UserProfile.objects.get_or_create(user=user )
p[0].mobile = self.cleaned_data['mobile']
p[0].address = self.cleaned_data['address']
p[0].save()
return user