form.is_valid() always returns false - python

I have tried all the solutions given on SO but was not able to slve this
view.py
def signup(request):
form = SignupForm(request.GET)
print("%s"%request.GET['hobby'])
form.errors
#h=SignupForm(request.POST)
if form.is_valid():
email = request.GET['email']
location = request.GET['location'] users=User(username=username,email=email,password=request.GET['password'],location=location)
user_profile = request.user.profile
user_profile.location = location
user_profile.save()
form.save()
return HttpResponseRedirect('mtweet/')
return render(request,'mtweet/signup.html',{'SignupForm':form})
form.py
class SignupForm(UserCreationForm):
username=forms.CharField(label = " Username",required=True)
email = forms.EmailField(label = "Email",required=True)
password = forms.CharField(widget = forms.PasswordInput,required=True)
location=forms.CharField(label="Location",required=False)
class Meta:
model = User
fields = ("username", "email","location")
signup.html
<div id="register">
<form method="post" action="{% url 'mtweet.views.signup' %}">
{% csrf_token %}
<table>
{{ SignupForm.as_p}}
</table>
<input type="submit" value="Submit" />
</form>
</div>

There are a few problems with your code; let me try and re-write it:
class SignupForm(forms.Form):
username=forms.CharField(label = " Username",required=True)
email = forms.EmailField(label = "Email",required=True)
password = forms.CharField(widget=forms.PasswordInput,required=True)
location=forms.CharField(label="Location",required=False)
def signup(request):
form = SignupForm(request.POST, request.FILES)
if form.is_valid():
email = form.cleaned_data['email']
location = form.cleaned_data['location']
password = form.cleaned_data['password']
username = form.cleaned_data['username']
user = User.objects.create_user(username, email, password)
user.save()
user_profile = user.profile
user_profile.location = location
user_profile.save()
return HttpResponseRedirect('mtweet/')
else:
return render(request,'mtweet/signup.html',{'SignupForm':form})
return render(request,'mtweet/signup.html',{'SignupForm':SignupForm()})

Related

customer registration not showing in django admin

Trying to create customer registration form for ecommerce website . No errors while submitting the form, but details are not shown in django admin . Here are required codes :
models.py
class Customer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
full_name = models.CharField(max_length=200)
address = models.CharField(max_length=200, null=True, blank=True)
joined_on = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.full_name
urls.py
urlpatterns = [path("register",views.register, name="register")]
forms.py
class CustomerRegistrationForm(forms.ModelForm):
username = forms.CharField(widget=forms.TextInput())
password = forms.CharField(widget=forms.PasswordInput())
email = forms.CharField(widget=forms.EmailInput())
class Meta:
model = Customer
fields = ["username", "password", "email", "full_name", "address"]
def clean_username(self):
uname = self.cleaned_data.get("username")
if User.objects.filter(username=uname).exists():
raise forms.ValidationError(
"Customer with this username already exists.")
return uname
views.py
def register(request):
form = CustomerRegistrationForm(request.POST or None)
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
email = form.cleaned_data.get("email")
user = User.objects.create_user(username, email, password)
form.instance.user = user
return redirect("/")
return render(request,"register.html",{'form':form})
register.html
{% load crispy_forms_tags %}
<div class="container">
<div class="row">
<div class="col-md-6 mx-auto">
<h3>Customer Registration Form</h3><hr>
<form action="" method="POST">
{% csrf_token %}
{{form|crispy}}
<button class="btn btn-primary" >Register as a Customer</button>
</form>
<p> Already have an account? Login here</p>
</div>
</div>
</div>
Thank you in advance:)
In your view, you're creating Users, not Customers.
If you're starting a new project, I would suggest using a custom user model.
If that's not possible, you need to save the form first to generate a Customer instance and then connect it with the appropriate User model:
def register(request):
form = CustomerRegistrationForm(request.POST or None)
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
email = form.cleaned_data.get("email")
customer = form.save(commit=False)
user = User.objects.create_user(username, email, password)
customer.user = user
customer.save()
form.instance.user = user
return redirect("/")
return render(request,"register.html",{'form':form})

User is not authenticating

I am trying to create a simple login page. But user is always returned as none.
Here's my login.html
<form method = 'POST'>
{% csrf_token %}
<div class="body"></div>
<div class="name">
<div>Chili<span>Pili</span></div>
</div>
<br>
<div class="login">
<input type="text" placeholder="Username" name="username"><br>
<input type="password" placeholder="Password" name="password"><br>
<input type="submit" value="Login">
</div>
</form>
my login function in view.py
def login(request):
if request.method == "POST":
username = request.POST['username']
password = request.POST['password']
user = authenticate(username = username, password = password)
if user is not None:
login(user)
print (user)
messages.success(request, "You have successfully Logged In.")
return redirect('index')
else:
messages.error(request, "You have entered invalid credentials. Please try again")
return redirect('login')
else:
return render(request, 'main/login.html')
models.py:
class users(models.Model):
_id = models.AutoField
name = models.CharField(max_length = 100)
username = models.CharField(max_length = 100)
email = models.EmailField(max_length=254)
hpassword = models.CharField(max_length = 255)
category = models.CharField(max_length=50, default= "teacher")
def __str__(self):
return self.name
return self.username
return self.email
return self.category
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = [username, hpassword]
The keeps returning as none and only else statement gets executed. I am not able to understand what is going wrong here
try
def loginview(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
...
else:
...
the reason why you are getting that error is login(request,user) is recuring back to login view method rather thatn using auth login method.... change login view method name to "loginview" that will be fine.

'NoneType' object has no attribute 'set_password' in django registration and login

I am entirely new to django.
Trying to create login and registration system.
User registers successfully, saved in database but I get this error after registering.
"'NoneType' object has no attribute 'set_password'"
views.py
def register(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
form.save()
username = form.cleaned_data.get('username')
fullname = form.cleaned_data.get('fullname')
password = form.cleaned_data.get('password1')
user = authenticate(request, username=username, password=password)
messages.success(request, f'Welcome to blaza {fullname}')
user.set_password(password)
user.save()
if user is not None:
login(request, user)
return redirect(reverse('home'))
else:
form = SignUpForm()
return render(request, 'accounts/signup.html', {'form': form})
When I remove "user.set_password" it works but registered users can not login with their credentials even when the username and password is correct, It says incorrect username and password. (only admin account, superuser can login).
So I researched and had to add the user.set_password and user = form.save (I get warning that local variable user value is not used)
forms.py
class SignUpForm(UserCreationForm):
username = forms.CharField(max_length=50)
fullname = forms.CharField(max_length=200)
email = forms.EmailField(max_length=200)
password2 = None
class Meta:
model = User
fields = ('username', 'fullname', 'email', 'password1')
def clean_password1(self):
password1 = self.cleaned_data.get('password1')
try:
password_validation.validate_password(password1, self.instance)
except forms.ValidationError as error:
self.add_error('password1', error)
return password1
Models.py
class CustomUser(AbstractUser):
class Meta:
db_table = 'users'
fullname = models.CharField(max_length=200)
email = models.EmailField(max_length=150)
profile_photo = models.ImageField(upload_to='images/profile_pics', default='images/nophoto.png')
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$',
message="Phone number must be entered in the format: '+999999999'. Up to 15 "
"digits "
"allowed.")
phone_number = models.CharField(validators=[phone_regex], max_length=13, default='')
address = models.CharField(max_length=100, default='')
has_store = models.BooleanField(default=False)
signup.html
<form method="post">
{% csrf_token %}
{% for field in form %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit">Sign up</button>
</form>
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', TemplateView.as_view(template_name='home.html'), name='home'),
path('accounts/', include('users.urls')),
path('accounts/', include('django.contrib.auth.urls')),
]
Or Someone help me with a secured and working registration and login that actually works.
In a simple signup form:
def register(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
fullname = form.cleaned_data.get('fullname')
password = form.cleaned_data.get('password1')
saved_user = form.save(commit=False)
saved_user.set_password(password)
saved_user.save()
user = authenticate(request, username=username, password=password)
messages.success(request, f'Welcome to blaza {fullname}')
if user is not None:
login(request, user)
return redirect(reverse('home'))
else:
form = SignUpForm()
return render(request, 'accounts/signup.html', {'form': form})
The reason you get noneType because you save user after the authenticate() so it return None

Django : NoReverseMatch at when changing password using form

I'm trying to make form and method which allows users to change their password. When user type their password into two inputs than form will check if those are same and update db. However I got this error and I couldn't solve it.
error message
NoReverseMatch at /blog/password_change/blue/
Reverse for 'profile' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'blog/profile/(?P<username>[-\\w.]+)/$']
urls.py
url(r'^password_change/(?P<username>[-\w.]+)/$', views.password_change, name='password_change'),
url(r'^profile/(?P<username>[-\w.]+)/$', views.profile, name='profile'),
views.py
def password_change(request, username):
if request.method == 'POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
return redirect(reverse('blog:profile'))
else:
return redirect(reverse('blog:profile'))
else:
form = PasswordChangeForm(user=request.user)
return HttpResponseRedirect('/blog/')
profile.html. this is the template.
<form class="form-horizontal" role="form" action="{% url'blog:password_change' user.username %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<label for="password1">new password</label>
<div class="row">
<input type="password" name="password1" id="password1"/></div>
<div class="row">
<label for="password2">password check</label></div>
<div class="row">
<input type="password" name="password2" id="password2"/></div>
<div class="row">
<button type="submit" class="button-primary">change password</button></div>
views.py
def password_change(request, username):
if request.method == 'POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
return redirect(reverse('blog:profile'))
else:
return redirect(reverse('blog:profile'))
else:
form = PasswordChangeForm(user=request.user)
return HttpResponseRedirect('/blog/')
This is forms.py
class PasswordChangeForm(forms.ModelForm):
error_messages = {
'password_mismatch': ("The two password fields didn't match."),
}
password1 = forms.CharField(
label=("Password"),
strip=False,
widget=forms.PasswordInput,
help_text=password_validation.password_validators_help_text_html(),
)
password2 = forms.CharField(
label=("Password confirmation"),
widget=forms.PasswordInput,
strip=False,
help_text=("Enter the same password as before, for verification."),
)
class Meta:
model = User
fields = ("username",)
field_classes = {'username': UsernameField}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self._meta.model.USERNAME_FIELD in self.fields:
self.fields[self._meta.model.USERNAME_FIELD].widget.attrs.update({'autofocus': True})
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError(
self.error_messages['password_mismatch'],
code='password_mismatch',
)
self.instance.username = self.cleaned_data.get('username')
password_validation.validate_password(self.cleaned_data.get('password2'), self.instance)
return password2
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
As your error states, you need an argument for your username in profile url, which you don't provide at all.
For example:
return redirect(reverse('blog:profile'))
should be
return redirect(reverse('blog:profile', args=[form.user.get_username()]))
You must pass username to reverse().
username = form.user.get_username()
reverse('blog:profile', kwargs={'username':username})

form.is_valid is not validating

I'm trying to make register possible on the homepage (register box appears onclick), so I don't have a seperate URL to handle registration. I'm trying to send the form through get_context_data, however it's not working. Here's my code:
forms.py
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
confirm_password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = [
'username',
'password',
'confirm_password',
]
views.py
class BoxesView(ListView):
template_name = 'polls.html'
def get_context_data(self):
context = super(BoxesView, self).get_context_data()
# login
form = UserRegistrationForm(self.request.POST or None)
context['form'] = form
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = User.objects.create_user(username, password)
user.save()
return redirect('/')
return context
return context
def get_queryset(self):
pass
base.html
<form action="" enctype="multipart/form-data" method="post">{% csrf_token %}
<div class="registerBox">
{{ form.username }}
{{ form.password }}
<input type="submit" value="register"/>
</div>
</form>
The fields show up but after submitting the form it doesn't create a User because my form.is_valid is False. Any idea?
You shouldn't return a response from get_context_data(). Instead, do that in the post() method like this:
class BoxesView(ListView):
template_name = 'polls.html'
def post(self, request, *args, **kwargs):
form = UserRegistrationForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = User.objects.create_user(username, password=password)
return redirect('/')
else:
return self.get(request, *args, **kwargs)
def get_context_data(self):
context = super(BoxesView, self).get_context_data()
context['form'] = UserRegistrationForm()
return context
Looks like your Form expects to have confirm_password submitted, but that's not part of your html form.

Categories