problem using django's User authentication model. Uncomprehensible error - django

I want to register users.
So I made a:
class RegisterForm(ModelForm):
class Meta:
model=User #(from django.auth.contrib.User)
now i display that form in a template for the users to fill it and to submit it.
When i do form.is_valid(), i get this validation error: Your username and password didn't match. Please try again.
Does anyone know what can cause this?
i've included the ModelForm, the view that processes the registration form and the template that displays the registration form.
Thank you for your time and kind concern.
MY MODEL FORM
class RegisterForm(ModelForm):
class Meta:
model=User
THE VIEW THAT HANDLES THE REGISTRATION
def register(request):
if request.method=='POST':
form=RegisterForm(request.POST)
if form.is_valid(): # HERE I GET A VALIDATION ERROR
new_user=User.objects.create_user(username=form.cleaned_data['username'],
password=form.cleaned_data['password'],
email=form.cleaned_data['email'],
)
new_user.is_active=True
new_user.first_name=form.cleaned_data['first_name']
new_user.last_name=form.cleaned_data['lastname']
return HttpResponseRedirect(reverse('confirm_registered'),args=[form.cleaned_data['username']])
else:
return render(request,'login/register.html',{'form':form})
else:
raise ValueError()
THE REGISTRATION TEMPLATE
{% extends "store/index2.html" %}
{% block canvas %}
<h3>Registration</h3>
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action="/retailstore/login/register.html">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
<tr>
<td>{{ form.first_name.label_tag }}</td>
<td>{{ form.first_name }}</td>
</tr>
<tr>
<td>{{ form.last_name.label_tag }}</td>
<td>{{ form.last_name }}</td>
</tr>
<tr>
<td>{{ form.email.label_tag }}</td>
<td>{{ form.email }}</td>
</tr>
</table>
<input type="submit" value="register" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{% endblock %}

The form is not validating, but your template is set to always show the same error message about username and password not matching:
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
The reason it is not validating is probably because you are only using some of the fields from the User object, and a ModelForm expects all of the non-editable fields. In the Form's Meta, set
fields = 'username', 'password', 'first_name', 'last_name', 'email'
to tell it to only require those fields.
Also note that passwords are not stored in the database as plain text, so creating a user with a password like that will not work. You need to use user.set_password(form_password).

As Dave points out, you always show the same message no matter what the validation error. You should do this:
{% if form.errors %}
{{ form.errors }}
{% endif %}

Related

How to obtain cleaned_data from a FormSetView (django-extra-views)

I cannot see how to trigger and obtain the cleaned_data from my FormSetView. With a django formset, I would call is_valid() on the formset within a POST'ed response, but not sure how to do that here. Examples in documentation do not show this, afaics.
I've implemented exactly as per the example in django-extra-views documentation. I already have a ModelFormSetView working fine although the DB update is automatic in that case. However, in this case of non-model implementation the cleaned data necessarily needs to be massaged into a different format for DB storage.
My view (called from the url entry):
class TemplateFSView(FormSetView):
template_name = 'template_season.html'
form_class = TemplateForm
success_url = 'tee/home/'
def get_initial(self):
# initial data is a pre-load test for now...
return [{'commence': '07:30', 'finish': '22:00', "spacing": "10"]
def formset_valid(self, formset):
# do whatever you'd like to do with the valid formset
print('How do I get here?')
return super(TemplateFSView, self).formset_valid(formset)
Form:
class TemplateForm(forms.Form):
commence = forms.CharField(required=True, label='first tee-time')
finish = forms.CharField(required=True, label='last tee-time')
spacing = forms.CharField(required=True, label='tee spacing')
Template:
<form method="post">
{% csrf_token %}
<table>
{% for form in formset %}
{% if forloop.counter == 1 %}
<thead>
<tr>
<th scope="col">{{ form.commence.label_tag }}</th>
<th scope="col">{{ form.finish.label_tag }}</th>
<th scope="col">{{ form.spacing.label_tag }}</th>
</tr>
</thead>
{% endif %}
<tr>
<td>{{ form.commence }}</td>
<td>{{ form.finish }}</td>
<td>{{ form.spacing }}</td>
</tr>
{% endfor %}
</table>
{{ formset.management_form }}
<input type="submit" value="Submit" />
</form>

Django request is launched automatically

I'm getting a little issue and I don't remember the way to solve my problem.
I have a template which let to query database and get a result according to user's criteria.
My view looks like :
#login_required
def Identity_Individu_Researching(request) :
query_lastname_ID = request.GET.get('q1ID')
query_firstname_ID = request.GET.get('q1bisID')
query_naissance_ID = request.GET.get('q1terID')
sort_params = {}
set_if_not_none(sort_params, 'id__gt', query_lastname_ID)
set_if_not_none(sort_params, 'Prenom__icontains', query_firstname_ID)
set_if_not_none(sort_params, 'VilleNaissance', query_naissance_ID)
query_ID_list = Individu.objects.filter(**sort_params)
return render(request, 'Identity_Individu_Recherche.html', context)
But this request is launched automatically when the template is loaded.
In my HTML template, I have :
<form autocomplete="off" method="GET" action="">
<input type="text" name="q1ID" placeholder="Nom (ex:TEST) " value="{{ request.GET.q1ID }}"> et
<input type="text" name="q1bisID" placeholder="Prénom (ex:Test)" value="{{ request.GET.q1bisID }}">
<input type="text" name="q1terID" placeholder="Ville Naissance" value="{{ request.GET.q1terID }}"> (optionnel)
<input class="button" type="submit" name="recherche" value="Rechercher">
</form>
<br></br>
<table style="width:120%">
<tbody>
<tr>
<th>ID</th>
<th>État</th>
<th>N° Identification</th>
<th>Civilité</th>
<th>Nom</th>
<th>Prénom</th>
<th>Date de Naissance</th>
<th>Ville de Naissance</th>
<th>Pays de Naissance</th>
<th>Institution</th>
</tr>
{% for item in query_ID_list %}
<tr>
<td>{{ item.id}}</td>
<td>{{ item.Etat}}</td>
<td>{{ item.NumeroIdentification}}</td>
<td>{{ item.Civilite }}</td>
<td>{{ item.Nom }}</td>
<td>{{ item.Prenom }}</td>
<td>{{ item.DateNaissance }}</td>
<td>{{ item.VilleNaissance }}</td>
<td>{{ item.PaysNaissance }}</td>
<td>{{ item.InformationsInstitution }}</td>
</tr>
{% endfor %}
</tbody>
</table>
So How I can launch the queryset only if user submit the form with the form button ? I know it's based on name = "jhjh"
You should check if the request contains the form data.
if 'recherche' in request.GET:
...
You can change method for your form in template
<form autocomplete="off" method="POST" action="">
<!-- ^^^^^ -->
in the view:
query_ID_list = Individu.objects.all()
if request.method == 'POST':
# your logic
query_ID_list = query_ID_list.filter(**sort_params)
return render(request, 'Identity_Individu_Recherche.html', context)

Django-- Get model fields in template only for current user

First of all, I know there are lot of questions about accessing model in template but let me explain why this is different.
I want profile page where User can see their details. I am able to do that but with one little bug. If there are 3 Users(say A, B,C) and User A want to see his profile he sees it three time. Like this:
How do I stop the loop after one iteration so that the User only get's his profile information once.
This is my URL:
url(r'^profile/$', views.IndexView.as_view(), name='profile'),
Views.py:
class IndexView(generic.ListView):
template_name = 'profile.html'
def get_queryset(self):
return Profile.objects.all()
and profile.html:
{% if user.is_authenticated %}
{% for profile in object_list %}
<h1>{{ request.user }}'s Profile</h1>
<table>
<tr>
<td>Username:</td>
<td>{{ user.username }}</td>
</tr>
<tr>
<td>First Name:</td>
<td>{{ user.first_name }}</td>
</tr>
<tr>
<td>Last Name:</td>
<td>{{ user.last_name }}</td>
</tr>
<tr>
<td>Email:</td>
<td>{{ user.email }}</td>
</tr>
<tr>
<td>Personal Info:</td>
<td>{{ user.profile.personal_info }}</td>
</tr>
<tr>
<td>Job Title:</td>
<td>{{ user.profile.job_title }}</td>
</tr>
<tr>
<td>Department:</td>
<td>{{ user.profile.department }}</td>
</tr>
<tr>
<td>Location:</td>
<td>{{ user.profile.location }}</td>
</tr>
<tr>
<td>Expertise:</td>
<td>{{ user.profile.expertise }}</td>
</tr>
<tr>
<td>Phone Number:</td>
<td>{{ user.profile.phone_number }}</td>
</tr>
<tr>
<td>Contact Skype:</td>
<td>{{ user.contact_skype }}</td>
</tr>
<tr>
<td>Contact Facebook:</td>
<td>{{ user.contact_facebook }}</td>
</tr>
<tr>
<td>Contact Linkedin:</td>
<td>{{ user.profile.contact_linkedin }}</td>
</tr>
</table>
<form class="form-horizontal" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'form-template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<a href={% url 'profile_edit' %}><input type="button" class = " col-sm-offset-2 btn bk-bs-btn-warning " name="cancel" value="Edit" /></a>
</div>
</div>
</form>
{% endfor %}
{% else %}
<h2>Please login to see your Profile</h2>
{% endif %}
I am a newbie to django, thanks is advance.
You're looping over all Profile's but not actually using this data in the loop, instead you're using user.profile.
This means that you likely have 3 Profile objects in the database, then for each you display the details of the current user, which isn't desirable.
So you can remove the loop entirely, and just keep its contents that refer to all the user.profile attributes to achieve the desired result.
edit
Looks like user is passed into your template by default, and points to the currently logged in user. So user.profile will return the profile, and this works without doing anything else. So user.profile.personal_info is valid and should work. When you tried to use profile directly, that is not the same thing, and wasn't defined, so profile.personal_info didn't work. Then in your loop you used profile to loop over Profile objects, but this wasn't necessary or was used. Hope this makes sense.

request.POST.getlist returning None list in Django?

I have a html template like this:
<table border="1" align="center">
{% for result in result %}
<tr>
<td><input type="checkbox" name="choice" id="choice{{ forloop.counter }}" value="{{ choice }}" /></td>
<td><label for="choice{{ forloop.counter }}">{{ choice }}</label><br /></td>
<td>{{ result.file_name }}</td>
<td>{{ result.type }}</td>
<td>{{ result.size }}</td>
<td>{{ result.end_date }}</td>
<td>{{ result.source }}</td>
{% endfor %}
</tr>
</table>
{{ c }}
<h4>Delete File</h4>
result variable is generated from:
def uploaded_files(request):
log_id = request.user.id
b = File.objects.filter(users_id=log_id, flag='F') #Get the user id from session .delete() to use delete
return render_to_response('upload.html', {'result': b}, context_instance=RequestContext(request))
This is where I try to get the value from choice from template:
def delete_files(request):
log_id = request.user.id
choices = request.POST.getlist('choice') #Get the file name from the as a list
for i in choices:
File.objects.filter(users_id=log_id, file_name=i).update(flag='D')
return render_to_response('upload.html', {'c': choices}, context_instance=RequestContext(request))
Include [] after choice because you are getting array form request
choices = request.POST.getlist('choice[]')
this will solve your prob
As Rohan mentioned in the comment, you have no <form> tag in the template, and appear to be simply assuming that clicking on a normal <a> link will submit some data. That's not at all how it works: if you want to submit data from input elements, they need to be inside a <form>, you need to set the action of that form appropriately, and you need to submit it using a <input type="submit"> (or button) rather than a link.
This is basic HTML, by the way, not Django.

How to add a button for password request in django login?

In my django App on the login page i want to have a request password button which functions like, when this button is clicked I get a request from the user per email to provide that user a password for the site.At the template login.html I made this change :
{% extends "base.html" %}
{% load url from future %}
{% block site_contents %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action="{% url 'django.contrib.auth.views.login' %}">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" name="request_password" value="Request Password" />
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{% endblock %}
Where in views can I write code to capture the event request_password and write my code to email to the amdin about user's request?
Thanks in advance
I think this would be easier to do by creating a new form and pointing it to your own view. Or, if you want to have it in one form, you can probably create a view along the lines of:
from django.contrib.auth.views login as original_login
def my_login(request):
if request.method == 'POST' and 'request_password' in request.POST:
# process password request somehow
else:
return original_login(request)
Modifying Django-supplied view would probably just complicate things for you in the long run.