I am new to Django and was following a tutorial on how to build a register view. I did exactly the same but my form does not pass form.is_valid().
Here is what I did:
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']
if commit:
user.save()
return user
views.py
def register_user(request):
if request.method == 'POST':
form = MyRegistrationForm(request.POST)
if form.is_valid():
user = form.save()
return HttpResponseRedirect('/accounts/register_success')
form = MyRegistrationForm()
return render(request, 'register.html', {'form':form})
def register_success(request):
return render(request, 'register_success.html')
register.html
{% extends "base.html" %}
{% block content %}
<h2>Register</h2>
<form action="/accounts/register/" method="post">{% csrf_token %}
{{ form }}
<input type="submit" value="Register" />
</form>
{% endblock %}
When I tried to register new users on the webpage, none of them passed. Even when I used username: testuser email: testuser#example.com password:testuser123, it failed. So what is wrong?
Thanks in advance!
You should follow the correct view pattern. Put the line form = MyRegistrationForm() inside an else block, then the page itself will tell you why the form is not valid.
Related
This question already has answers here:
Django password fields placeholder
(3 answers)
Closed 3 years ago.
Django 1.11
I want to add a placeholder in all the forms I have,
I want to know why the password field has (None value)?
this is an image for clarification.enter image description here
I need to know how can I add password placeholder by forms.PasswordInput
forms.py
from django.contrib.auth.forms import User
from django import forms
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'email', 'password']
class EditForm(UserForm):
def __init__(self, form):
super(EditForm, self).__init__(form)
for key, field in self.fields.items():
if isinstance(field.widget, forms.TextInput) or \
isinstance(field.widget, forms.EmailInput) or \
isinstance(field.widget, forms.PasswordInput):
field.widget.attrs.update({'placeholder': field.label})
register.html
{% extends 'base.html' %}
{% block title %} Register {% endblock %}
{% block body %}
<div class="register">
<div class="container">
<h1>Register</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Registier</button>
</form>
</div>
</div>
{% endblock %}
views.py
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm
from django.views import View
from .forms import UserForm, EditForm
from django.contrib.auth import authenticate
def index(request):
return render(request, 'account/index.html')
class UserRegister(View):
form_class = EditForm
template_name = 'account/register.html'
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
username = form.cleaned_data['username']
password = form.cleaned_data['password']
email = form.cleaned_data['email']
user.set_password(password)
user.save()
user = authenticate(username=username, email=email, password=password)
return redirect('account:home')
return render(request, self.template_name, {'form': form})
Try
class UserForm(forms.ModelForm):
password = forms.CharField(label='password',widget=forms.PasswordInput((attrs={'placeholder': 'Password'})))
Okay I'm confused.
I'm trying to build a login page, but whenever I try to login, django gives the error that the username already exists. I haven't used save() anywhere.
I'm using authenticate(), I referred the Django docs for that:
https://docs.djangoproject.com/en/1.10/topics/auth/default/#how-to-log-a-user-in
Here is my code, please tell me where I'm going wrong:
forms.py
class LoginForm(forms.ModelForm):
username = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Username'}))
password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
class Meta:
model = User
fields = ['username', 'password']
views.py
class LoginFormView(View):
form_class = LoginForm
template_name = 'login.html'
# display a blank form
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
# authenticate user
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('slrtcebook:home')
return render(request, self.template_name, {'form': form})
login.html
<div class="form-container">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
{{ field }}
{{ field.errors }}
{% endfor %}
<input id="submit" type="submit" value="Log in" />
</form>
</div>
<p>Don't have an account? Register here</p>
Don't use a ModelForm for this; it will assume you're trying to create a user, and validate that you can do so with the data you've entered. Just use a standard form - inherit from forms.Form and remove the Meta class.
For those of you who want the code here is what I did to fix it:
inside of views.py:
class UserLoginView(View):
form_class = LoginForm
template_name = 'music/login_form.html'
#display a blank form
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
#proces form data
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
# user = form.save(commit=False)
#cleaned (normalized) data
username = form.cleaned_data['username']
password = form.cleaned_data['password']
# user.set_password(password) #this is the only way to change a password because of hashing
#returns the User obejects if credintials are correct
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('music:index')
return render(request, self.template_name,{'form': form})
inside of froms.py:
class LoginForm(forms.Form):
username = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Username'}))
password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
fields = ['username', 'password']
don't forget to also import LoginForm at the top of views.py, where you import UserForm:
from .forms import UserForm, LoginForm
I'm trying to create a custom form where the user can also enter his name for instance but I am facing an issue, when the registration is done the name is not saved and I can't show it on the template.
here is the code
views.py
def register_user(request):
if request.user.is_authenticated():
return HttpResponseRedirect('/user/')
else:
if request.method == 'POST':
form = MyRegistrationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/user/')
context = {}
context.update(csrf(request))
context['form'] = MyRegistrationForm()
return render(request, 'register.html', context)
forms.py
class MyRegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
name = forms.CharField(required=True)
class Meta:
model = User
fields = {'name', 'username', 'password1', 'password2', 'email'}
def save(self, commit=True):
user = super(MyRegistrationForm, self).save(commit=False)
user.email = self.cleaned_data['email']
user.name = self.cleaned_data['name']
if commit:
user.save()
return user
register.html
<form action="/user/register/" method="post" id="register" autocomplete="off">
{% csrf_token %}
<div class="fieldWrapper">
{{ form.name.errors }}
{{ form.name.label_tag }}
{{ form.name }}
</div>
[... other form fields ...]
</div>
<input type="submit" value="Register"/>
</form>
So when I submit the form, everything works but when I try to show {{ user.name }} in the template, nothing is shown, why is that? (it works for the email field)
The default User object doesn't have a name field (so you are actually just saving the content of your name field to the object, and not the database). It has a first_name and last_name so you can either use those fields instead or you can customize the User model to have a separate name field
Edit
Also, just so you know, if you use the first_name and last_name fields instead, the User model has a get_full_name() method built-in which might be useful
The User does not have a "name" field. Try:
{{ user.username }}
In my application, I used email and password for user authentication, which works fine. However, I want to offer the user the option of adding other information to their account like first names, last names, and dates of birth.
I have a change form in myapp.forms.py
class MyChangeForm(forms.ModelForm):
"""
Form for editing an account.
"""
first_name = forms.CharField(widget=forms.TextInput, label="First name")
last_name = forms.CharField(widget=forms.TextInput, label="Last name")
date_of_birth = forms.DateField(widget=forms.DateField, label="Date of birth")
class Meta:
model = MyUser
fields = ['first_name', 'last_name', 'date_of_birth']
def save(self, commit=True):
user = super(MyChangeForm, self).save(commit=False)
if commit:
user.save()
return user
in my views.py, I have the following method for updating
#login_required(login_url='/')
def update_user(request):
if request.method == 'POST':
form = MyChangeForm(request.POST, instance=request.user)
if form.is_valid():
user = form.save(commit=False)
user.save()
return HttpResponseRedirect('/')
else:
form = MyChangeForm(instance=request.user)
return render_to_response('update_user.html', context_instance=RequestContext(request))
and my update_user.html is as follows
{% extends 'user_base.html' %}
{% block content %}
<div class="col-sm-3 col-sm-offset-5">
<h1> Update User</h1>
<form method='POST' action='/update_user/'> {% csrf_token %}
<ul>
{{ form.as_table }}
</ul>
<input type='Submit' class='btn btn-primary btn-block'>
</form>
</div>
{% endblock %}
However, when I serve the file I see this:
As seen here, there's no way to enter my fields!
How can I fix this? It's probably easy, but I'm getting tunnel vision.
erip
Add form to the context, for example like this:
render('update_user.html', {'form': form})
I am trying to display my users information but I am getting anonymous user as my output;
Anonymous User
My code in my views.py is as follows;
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return redirect('/account')
else:
form = RegistrationForm()
args = {'form' : form}
return render(request, 'accounts/register.html', args)
def view_profile(request):
args = {'user': request.user}
return render (request, 'accounts/profile.html',args)
I am over-riding the UserCreationForm, my code in forms.py is;
class RegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = {
'username',
'first_name',
'last_name',
'email',
'password1',
'password2'
}
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
My profile.html where I want my profile information to be displayed is;
{% block head %}
<title> User Profile </title>
{% endblock %}
{% block body %}
<div class="container">
<p>
<h1> {{user}}</h1>
<h3>First Name: {{user.first_name}}</h3>
<h3>Last Name: {{user.last_name}}</h3>
<h3>Email: {{user.email}}</h3>
</p>
</div>
{% endblock %}
Really not sure where I am going wrong any help is greatly appreciated.
you must decorate your def view_profile(request): with #login_required, otherwise Django will serve this request also to Anonymous users.
Also note that if you have (or add) django.core.context_processors.request to your settings.TEMPLATE_CONTEXT_PROCESSORS
(or settings.TEMPLATES['OPTIONS']['context_processors'] depending your django version) you can use {{request.user}} in your template without create specific entry in context.