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.
Related
I am trying to make a simple to-do list in Django that each user could have their own task list so when they logged in they add a task and its save for themselves and the list only display their own tasks, but when I try to add a task from the template's form it won't save but when I add task manually from admin panel it work.
my models.py
from django.db import models
from django.contrib.auth.models import User
class Tasks(models.Model):
user = models.ForeignKey(User, null=True,on_delete=models.CASCADE)
title = models.CharField(max_length=200)
check = models.BooleanField(default = False)
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
forms.py
from django import forms
from django.forms import ModelForm
from .models import *
class TaskForm(forms.ModelForm):
class Meta:
model = Tasks
fields = '__all__'
views.py:
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .forms import *
from .models import Tasks
#login_required(login_url = 'login')
def tasks(request):
tasks = Tasks.objects.filter(user = request.user)
context = { 'tasks': tasks }
return render(request,'ToDo/list.html',context)
#login_required(login_url = 'login')
def add_task(request):
form = TaskForm()
if request.method == 'POST':
form = TaskForm(request.POST)
if form.is_valid():
form.save(commit=False)
form.user = request.user
form.save()
return redirect('/')
context = {'form' : form}
return render(request,'ToDo/add.html',context)
where is the problem?
You assign the user to the .user attribute of the form, not of the .instance wrapped in the form. You thus should alter the instance with:
#login_required(login_url = 'login')
def add_task(request):
if request.method == 'POST':
form = TaskForm(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.save()
return redirect('/')
else:
form = TaskForm()
return render(request, 'ToDo/add.html', {'form' : form})
You should furthermore only redirect in case of a successful POST request: in case the POST request is not successful, the form can render the error messages, and thus will inform the user what the problem is.
Furthermore you make the user field non-editable:
from django.conf import settings
class Tasks(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
editable=False,
on_delete=models.CASCADE
)
title = models.CharField(max_length=200)
check = models.BooleanField(default = False)
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
I am pretty new to django and I am trying to add email field to the UsercreationForm. However, I am getting the below error:
TypeError: UserRegisterForm() missing 1 required positional argument: 'UserCreationForm'
I was wondering if someone can suggest me by seeing my views.py and forms.py that where I am going wrong with my coding?
Views.py
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import UserRegisterForm
def home(request):
return render(request, 'index.html')
def task(request):
return render(request, 'task.html')
def register(request):
if request.method == "POST":
form = UserRegisterForm(request.POST)
if form.is_valid():
users = form.cleaned_data.get('username')
return redirect('home')
else:
form = UserRegisterForm()
return render(request, 'registration/register.html', {'form':form})
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
def UserRegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ["username","email", "password1", "password2"]
You wrote def making UserRegisterForm a function, but it should be a class:
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'email']
By making it a function, it requires a parameter UserCreationForm (so this is not interpreted as the base class). Furthermore it would not work, since the ModelForm class contains logic to make a form.
Furthermore 'password1' and 'password2' are not fields of the model. These are implemented in the UserCreationForm as form fields, and implement logic to handle the password as you can see in the source code of the UserCreationForm [GitHub].
So I have almost completed my Django app. But whenever I create the new user, his/her profile is not created automatically and when I open the profile after logging in, I get this error RelatedObjectDoesNotExist at /esacp/profile/ User has no profile
My signals.py is below:
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile
#receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()
My views.py of register() and profile() are below:
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'Your Student Account has been created! You can log in ESACP now.')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})
#login_required
def profile(request):
if request.method == 'POST':
u_form = UserUpdateForm(request.POST, instance=request.user)
p_form = ProfileUpdateForm(request.POST,
request.FILES,
instance=request.user.profile)
if u_form.is_valid() and p_form.is_valid():
u_form.save()
p_form.save()
messages.success(request, f'Your Profile information has been updated.')
return redirect('profile')
else:
u_form = UserUpdateForm(instance=request.user)
p_form = ProfileUpdateForm(instance=request.user.profile)
context = {
'u_form': u_form,
'p_form': p_form
}
My forms.py is below:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
first_name = forms.CharField(max_length=50)
last_name = forms.CharField(max_length=50)
class Meta:
model = User
fields = ['username', 'first_name', 'last_name', 'email', 'password1', 'password2']
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'first_name', 'last_name', 'email']
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['image']
and my apps.py is below:
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals
Everything to me seems to be fine, anyone knows what's wrong or what am I missing?
It seems like your receivers are not working
Check if you have,
INSTALLED_APPS = [
....
users.apps.UsersConfig
]
if UsersConfig is not there, it will not be initialized and ready wont be executed, resulting in not importing your receivers
or you can add in init.py inside users app
default_app_config = 'users.apps.UsersConfig'
To ensure receiver works, just add print("I'm working") inside receivers functions and watch the console
I have a signup form which I have defined below
forms.py
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from django import forms
class SignUpForm(UserCreationForm):
display_name = forms.CharField(max_length=30, required=True, help_text='Please provide a display name for your profile')
class Meta:
model = User
fields = ('username', 'password1', 'password2', 'display_name')
In the views.py, I handle the signup process
views.py
from django.contrib.auth.models import User
from django.contrib.auth import login, authenticate
from .forms import SignUpForm
from django.shortcuts import render, redirect
#csrf_exempt
def signup_users(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
username = form.cleaned_data.get('username')
display_name = form.cleaned_data.get('display_name')
raw_password = form.cleaned_data.get('password1')
user.set_password(raw_password)
user.display_name = display_name
user.save()
user = authenticate(username=username, password=raw_password)
print("signup authencticate", user)
login(request, user)
return render(request, 'index.html')
else:
form = SignUpForm()
return render(request, 'signup.html', {'form': form})
The user is able to signup successfully however their display_name doesn't get stored in the django User model.Even in the django admin, I do not see the field display_name.I have even performed a query like serializers.serialize("json",User.objects.filter(username=username)) but even here it shows every other field except the display_name.
What am I doing wrong?
Well quite simply the django.contrib.auth.models.User model has not field named display_name so of course it doesn't get saved. If you want to add fields to your User model you'll have to provide a custom User model.
I am trying to initiate a registration process for my website. I am using Python 3.3.5, and Django 1.6.
I receive an error saying No module named 'forms'. I am fairly new to Python/Django.
Here are my files:
Views.py:
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.core.context_processors import csrf
from django.contrib.auth.forms import UserCreationForm
from forms import MyRegistrationForm
def register_user(request):
if request.method == 'POST':
form = MyRegistrationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/register_success')
else:
form = MyRegistrationForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('register1.html', args)
def register_success(request):
return render_to_response('register_success.html')
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)
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2')
def save(self, commit=True):
user = super(MyRegistrationForm, self).save(commit=False)
user.email = self.cleaned_data['email']
# user.set_password(self.cleaned_data['password1'])
if commit:
user.save()
return user
the forms.py is located in the same folder as views.py. I tried from django.forms import MyRegistrationForm but then the error cannot import name MyRegistrationForm arises.
If you didn't change the default location of views.py, then it's likely to be in your application folder. Try something like from myapp.forms import MyRegistrationForm where myapp is the name of your application
if thats an app module, change your 6th line:
from forms import MyRegistrationForm
to:
from .forms import MyRegistrationForm
(just add a dot before forms)