As per youtube tutorial the user is created with exactly same method but mine doesn't work. Why?
views.py
from django.shortcuts import render,redirect
from .forms import CreateUserForm
def registerView(request):
form=CreateUserForm()
if request.method=="POST":
form=CreateUserForm(request.POST)
if form.is_valid():
form.save()
user=form.cleaned_data.get('username')
messages.success(request,'Account was successfully created for '+ user)
return redirect('login')
context={'form':form}
return render(request,"accounts/register.html", context)
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username','email','password1','password2']
Why is a user not created?
Related
So I want to save a Biographie for each new created User. The user can enter his Bio and it will the it to his Profile.
For this I created a model with OneToOneField
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class Profile(models.Model):
user = models.OneToOneField(
User, on_delete=models.CASCADE, null=True, blank=True)
bio = models.CharField(max_length=30)
To create the form I did the following in forms.py:
class BioForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('bio',)
Then I created in the views.py the saving, so the bio will be saved to the specific user:
from .forms import LoginForm, RegisterForm
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout, get_user_model
from django.contrib.auth import get_user_model
def test_view(request):
form = BioForm(request.POST)
user = get_user_model
if form.is_valid():
profile = form.save(commit=False)
profile.user = request.user
profile.phone_number = request.phone_number
profile.save()
return render(request, 'test.html', {'form': form})
There is something big wrong in the views.py but I don't get it.
I can submit the form and the form will be saved (sometimes) but without the user who wrote it + I get this error:
ValueError at /test/
Cannot assign "<SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x00000253B7140D00>>": "Profile.user" must be a "User" instance
Try to assign the user id instead
from .forms import LoginForm, RegisterForm
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout, get_user_model
from django.contrib.auth import get_user_model
def test_view(request):
form = BioForm(request.POST)
user = get_user_model
if form.is_valid():
profile = form.save(commit=False)
profile.user_id = request.user.id
profile.phone_number = request.phone_number
profile.save()
return render(request, 'test.html', {'form': form})
Your problem is that the user you try to save with, is not an authenticated user that exists in the database. Only authenticated (logged in) users exist in the database and can be used in a relational field
I am trying to create a user based app. A profile image is associated with every user. But whenever I am trying to login it is showing the above mentioned error and highlighting the instance.profile.save() in signals.py. I am new to django.
error:
Request Method: POST
Request URL: http://127.0.0.1:8000/login/
Django Version: 2.2.5
Exception Type: RelatedObjectDoesNotExist
Exception Value: User has no profile.
users/Signals.py:
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()
users/Models.py:
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
# Create your models here.
class profile(models.Model):
user=models.OneToOneField(User,on_delete=models.CASCADE)
image=models.ImageField(default='default.png',upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} profile'
def save(self,*args,**kwargs):
super( profile, self ).save(*args,**kwargs)
img=Image.open(self.image.path)
if img.height>300 or img.width>300:
output_size=(300,300)
img.thumbnail(output_size)
img.save(self.image.path)
users/views.py:
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 .models import profile
# Create your views here.
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'Account created for {username}!')
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 )
profile = profile.objects.get( user=request.user )
Profile_form = ProfileForm( request.POST, instance=profile )
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 Account is 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
}
return render(request,'users/profile.html',context)
app2/models.py:
from django.contrib.auth.models import User
from django.db import models
class resume( models.Model ):
user = models.OneToOneField( User, on_delete=models.CASCADE,primary_key=True )
username=models.CharField(max_length=150)
email=models.EmailField(max_length=150)
phone=models.BigIntegerField()
def __str__(self):
return str(self.user.username)+str(self.country)
This code
profile.objects.create(user=instance)
already saves the profile and doesn't need save() to be called separately in save_profile method.
Also please consider naming classes starting with uppercase. 'profile' -> 'Profile'
I am trying to write tests for my Django chat application to validate the UserCreationForm. I am following the Django test code here:
https://github.com/django/django/blob/master/tests/auth_tests/test_forms.py
I have a users app which handle registration, login, etc.
users/tests.py
from django.test import TestCase
from django.contrib.auth.forms import UserCreationForm
class UserCreationFormTest(TestCase):
def test_form(self):
data = {
'username': 'testuser',
'password1': 'test123',
'password2': 'test123',
}
form = UserCreationForm(data)
self.assertTrue(form.is_valid())
I've extended the UserCreation form to include an email field (forms.py) when registering.
users/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class UserRegisterForm(UserCreationForm):
email = forms.EmailField(required=True, label='Email')
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
I cannot for the life of me figure out why
form.is_valid()
always returns False during my testing. In my test I have
self.assertTrue(form.is_valid())
To execute tests I am running
python manage.py test users
from the terminal.
Actual registration, login, etc. works fine but my tests do not work as expected!
users/views.py
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid(): # check if valid
form.save() # save user info
messages.success(
request, f'Your account has been created. You are now able to login.')
return redirect('/users/login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form, 'title': 'Register'})
django forms doesn't save email in the database.i try all sort of things but still it is the only thing that is not saving .I need help
https://i.imgur.com/LJymHeS.png
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class UserRegistrationForm(UserCreationForm):
email=forms.EmailField()
class meta:
model=User
fields= ['username', 'email_address', 'password1','password2']
views.py code
register(request):
if request.method=='POST':
form=UserRegistrationForm(request.POST)
if form.is_valid():
form.save(commit=False)
username=form.cleaned_data['username']
password1=form.cleaned_data['password1']
password2=form.cleaned_data['password2']
email_address=form.cleaned_data['email']
form.save()
return redirect('/')
else:
form=UserRegistrationForm()
return render(request, 'blog/register.html',{'form':form})
The name of the field is email, not email_address. You thus should change this to:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class UserRegistrationForm(UserCreationForm):
email = forms.EmailField()
class meta:
model = User
fields = ['username', 'email']
Furthermore password1 and pasword2 are no model fields either. The UserCreationForm has some logic to compare the fields, and set a password.
In your register view, there is no need to unpack the cleaned data, you can just use form.save(). You can call login(request, user) if you want to automatically login the user you just created:
from django.contrib.auth import login
def register(request):
if request.method=='POST':
form = UserRegistrationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect('/')
else:
form = UserRegistrationForm()
return render(request, 'blog/register.html',{'form':form})
You can override the UserAdmin admin with:
# blog/admin.py
from blog.forms import UserRegistrationForm
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
admin.site.unregister(User)
#admin.register(User)
class NewUserAdmin(UserAdmin):
add_form_template = 'blog/register.html'
add_form = UserRegistrationForm
In django documentation the class used in UserCreationForm is Meta. you have to use capital M for meta class.You should get it correct when you have changed to capital M
class Meta:
model = User
fields = ['username', 'email']
The use case is that a logged in use, can call up their profile into a form, edit it and it gets updated in the database.
With the code below the correct Profile data can be viewed. It can also be called up into an editable form. The form allows the data to be edited , but when it is submitted, the database is NOT updated and the original profile is displayed.
I’ve tried everything, including console print statements so I know that it is getting to the POST portion of the code, is a valid form and doing the initial save().
Any insights would be appreciated (I am using Django 1.11). I do not want to start a rabbit running but the only thing I have not tried is breakink the OneToOne relationship with User and using a foriegnkey because I want the profile entry creaed when the user registers.
Notes:
When I popped this in for testing purposes: save_data.user = request.user
I get the error: Exception Value:'User' object has no attribute 'cleaned_data'`from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
Models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfile(models.Model):
user = models.OneToOneField(User)
description = models.CharField(max_length=100, default='')
city = models.CharField(max_length=100, default='')
website = models.URLField(default='')
phone = models.IntegerField(default=0)
balance = models.FloatField(default=0)
bank = models.FloatField(default=0)
image = models.ImageField(upload_to='profile_image', blank=True)
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
Forms.py
from django import forms
from django.contrib.auth.models import User
from .models import UserProfile
class ProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('description', 'city', 'phone', 'balance', 'bank', 'website', 'image')
Views.py
from __future__ import unicode_literals
from django.core.urlresolvers import reverse
from django.contrib.auth import login, authenticate, update_session_auth_hash
from django.contrib.auth.forms import (
UserCreationForm,
UserChangeForm,
PasswordChangeForm
)
from django.contrib.auth.models import User
from django.shortcuts import render, redirect
from core.forms import ( EditAccountForm, SignUpForm,
ProfileForm
)
from core.models import UserProfile
from django.views.generic import (TemplateView,ListView,
DetailView,CreateView,
UpdateView,DeleteView)
# Create your views here.
def edit_profile(request):
if request.method == 'POST':
form = ProfileForm(request.POST, instance=request.user)
if form.is_valid():
save_data = form.save()
save_data.user = request.user
print(save_data)
save_data.save()
return redirect(reverse('core:profile'))
else:
udata = UserProfile.objects.get(user=request.user)
form = ProfileForm(instance=udata)
args = {'form': form}
return render(request, 'core/test.html', args)
urls.py
from django.conf.urls import url
from django.contrib import admin
#from playme.core import views as core_views
from core import views as core_views
from django.contrib.auth import views as auth_views
# SET THE NAMESPACE!
app_name = 'core'
urlpatterns = [
url(r'^$', core_views.index, name='index'),
url(r'signup/$', core_views.signup, name='signup'),
url(r'^account/$', core_views.account, name='account'),
url(r'^profile/$', core_views.view_profile, name='profile'),
url(r'^login/$', auth_views.login, {'template_name': 'core/login.html'}, name='user_login'),
url(r'^logout/$', auth_views.logout, {'next_page': '/play/'}, name='logout'),
url(r'^edit_account/$', core_views.edit_account, name='edit_account'),
url(r'^edit_profile/$', core_views.edit_profile, name='edit_profile'),
url(r'^change_password/$', core_views.change_password, name='change_password'),
]
The URL I am hitting is:
http://127.0.0.1:8000/play/profile/
Which then goes to :
http://127.0.0.1:8000/play/edit_profile/
The form loads up but when submitted goes back to:
http://127.0.0.1:8000/play/profile/
With no database update.
I'm surprised this doesn't give an error.
When you instantiate the form on a GET, you correctly pass the UserProfile object as the instance parameter - this is correct because the form has that as its model. But when you instantiate on POST, you incorrectly pass the User object - request.user. You should pass the profile, as you do in the other branch.
Note, in both cases you can get the profile more simply by just doing request.user.userprofile.
Well the form being invalid situation isn't being handled here at all. Your code should look like this
def edit_profile(request):
if request.method == 'POST':
form = ProfileForm(request.POST, instance=request.user)
if form.is_valid():
save_data = form.save(commit=False)
save_data.user = request.user
save_data.save()
return redirect(reverse('core:profile'))
else:
udata = UserProfile.objects.get(user=request.user)
form = ProfileForm(instance=udata)
args = {'form': form}
return render(request, 'core/test.html', args)
Note the change in indentation.