Taking User Input to create Users in Django - django

I would like to create/add new users to my app in Django using the user input. I am using the default login provided by django. I am trying to add users to the default login. The example in https://docs.djangoproject.com/en/dev/topics/auth/:
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('john', 'lennon#thebeatles.com', 'john password')
passes the username and password. But i would like this to happen with user input. How do i do this?
Need some guidance...
I tried this but it doesn't seem to work:
def lexusadduser(request):
"""
add user
"""
if request.method == "POST":
user.save()
auth_user = authenticate(username=user.username,password=user.password)
if auth_user is not None:
lexusmain(request)
else:
return render('adduser.html')

First thing you need to do is create a ModelForm:
forms.py
from django.contrib.auth.models import User
class UserForm(ModelForm):
class Meta:
model = User
fields = ('username', 'email', 'password')
A ModelForm automatically builds your form off a model you provide. It handles the validations based on the fields.
views.py
from forms import UserForm
from django.contrib.auth import login
from django.http import HttpResponseRedirect
def lexusadduser(request):
if request.method == "POST":
form = UserForm(request.POST)
if form.is_valid():
new_user = User.objects.create_user(**form.cleaned_data)
login(new_user)
# redirect, or however you want to get to the main view
return HttpResponseRedirect('main.html')
else:
form = UserForm()
return render(request, 'adduser.html', {'form': form})
If its a POST request, we create a UserForm from the POST values. Then we check if its a valid form. If it is, we create the user, otherwise we return the form with the errors. If its not a POST request, we send a clean form
template
<form method="post" action="">
{% csrf_token %}
{{ form }}
<input type="submit" value="Create new user account" />
</form>

Use a form. Air coding here:
class SignupForm(forms.Form):
username = forms.CharField()
email = forms.EmailField()
password = forms.CharField(widget=forms.PasswordInput)

Related

Advice on Django user profile edit views

I'm building a Django app that will have users and profile models associated with them and they should have the ability to edit their profile in a view. As I see there are two similar but slightly different approaches how that could be done.
An UpdateView could be used that retrieves a pk from the url and then verifies if the pk corresponds to the actual authenticated user, for instance:
class ProfileUpdateView(UpdateView):
model = Profile
fields = ['field1', 'field2']
def get_object(self, queryset=None):
obj = super().get_object(queryset=queryset)
if obj.user != self.request.user:
# If the object user does not match the logged in user,
# raise a 404 Not Found exception.
raise Http404("You do not have permission to edit this profile.")
return obj
Or an alternative way that would check/ reference the current user via Django's authentication backend, for instance:
def profile_update(request):
profile = request.user.profile
form = ProfileForm(request.POST or None, instance=profile)
if form.is_valid():
form.save()
context = {'form': form}
return render(request, 'profile_update.html', context)
The main question is a bit generic, hence the name 'advice' in the post title, but are there any benefits/ risks associated with one or the other way of implementing a profile edit view that one should definitely consider when choosing between the two? The relationship between User and Profile model is a OneToOne relationship.
Thank's
I would not say it makes any difference, as long as only authenticated user can login in and one user can not modify other's profile. You can take any of the approaches, even implement the second approach in the first view (using /update/profile within Class Based View), like this:
class ProfileUpdateView(LoginRequiredMixin, UpdateView):
model = Profile
fields = ['field1', 'field2']
def get_object(self, queryset=None):
return self.request.user.profile
But you need to use LoginRequiredMixin with the view so that only authenticated users can log in.
A simpler way is to use the framework's own functions directly, for example, use login_required to check if a user is logged in, and forms to control user profile editing.
Here is my own code for your reference.
views.py
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import UserProfileForm
#login_required
def userinfo(request):
if request.method == 'POST':
form = UserProfileForm(request.POST)
if form.is_valid():
user = User.objects.get(pk=request.user.id)
user.first_name = form.cleaned_data['fullname']
user.email = form.cleaned_data['email']
user.save()
msg = "Profile updated!"
messages.add_message(request, messages.SUCCESS, msg)
return redirect('user.info')
else:
form = UserProfileForm()
context = {
'title': 'My Profile',
'form': form,
}
return render(request, 'accounts/info.html', context)
forms.py
from django import forms
class UserProfileForm(forms.Form):
fullname = forms.CharField(
label="Name",
error_messages={
'required': 'Required!',
})
email = forms.EmailField(
label="E-mail",
error_messages={
'required': 'Required!',
'invalid': 'The format is not correct!',
})

Custom Django Password Reset - Link does not get invalidated

I know that the one time link for the password reset should be invalidated following the email password change procedure as given here enter link description here. Yet, with my below implementation, although the link can reset the password each time, it does not get invalidated. The link works each time. What could be the reason for this ?
(I also see the last login timestamp is also updated in admin pages for the particular user that I am changing the password for)
(forms.py)
from django.contrib.auth.forms import UserCreationForm, SetPasswordForm
from django.contrib.auth import get_user_model
class ResetPasswordForm(SetPasswordForm):
class Meta:
model = get_user_model()
fields = ('password1', 'password2')
(tokens.py)
from django.contrib.auth.tokens import PasswordResetTokenGenerator import six
class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
def _make_hash_value(self, user, timestamp):
return (
six.text_type(user.pk) + six.text_type(timestamp) +
six.text_type(user.email_confirmed)
)
account_activation_token = AccountActivationTokenGenerator()
(views.py)
def activate_forgot_password(request, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
User = get_user_model()
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user is not None and account_activation_token.check_token(user, token):
if request.method == 'POST':
form = ResetPasswordForm(user, request.POST)
if form.is_valid():
user = form.save(commit=False)
print(user.password)
user.save()
login(request, user, backend='mysite.signup.views.EmailBackend')
return redirect('home')
else:
form = ResetPasswordForm(user)
return render(request,
'change_password.html',
{'form': form,
'uidb64': uidb64,
'token': token})
return render(request, 'account_forgot_password_token_invalid.html')
(template.html)
<form id="ResetPasswordForm" method="post" action="{% url 'activate_forgot_password' uidb64=uidb64 token=token %}" validate>
{% csrf_token %}
.
.
.
<div class="form-group">
<button type="submit" id="btn-signup" class="btn btn-block btn-primary btn-lg">Change Password</button>
</div>
</form>
The fields in _make_hash_value method never got update, the link still valid until one of the field assigned updated or the token timeout, you can add more fields to make sure that will trigger change like user.last_login or even user.password

How to retrieve data from extended user model

I am trying to make a simple signup/login page through django.
I have used UserCreationForm and used a model UserProfile to extend the user model.
I want to retrieve the data posted from form i.e department at my home page after user logged in.
I am new to django so brief explanation would be appreciated.
Thanks in advance
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from mysite.core.models import UserProfile
from django.db import models
class SignUpForm(UserCreationForm):
first_name = forms.CharField(max_length=30, required=False, help_text='Optional.')
department = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30, required=False, help_text='Optional.')
email = forms.EmailField(max_length=254, help_text='Required. Inform a valid email address.')
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email','password1', 'password2', 'department',)
def save(self, commit=True):
# Save the provided password in hashed format
user = super(SignUpForm, self).save(commit=False)
user_profile = UserProfile(user=user, department=self.cleaned_data['department'])
user.save()
user_profile.save()
return user, user_profile
views.py
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login, authenticate
from django.shortcuts import render, redirect
from mysite.core.forms import SignUpForm
#login_required
def home(request):
return render(request, 'home.html')
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user,user_profile = form.save(commit=False)
username = user.cleaned_data.get('username')
raw_password = user.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password)
login(request, user)
return redirect('home')
else:
form = SignUpForm()
return render(request, 'signup.html', {'form': form})
models.py
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE,unique=True)
department = models.CharField(max_length=500, blank=True)
home.html in templates:
{% extends 'base.html' %}
{% block content %}
<h2>Welcome, <small>{{ user.username }}</small>!</h2>
<p>Your email address: {{ user.email }}</p>
<p>Department: {{ user_profile.department }}</p>
{% endblock %}
I am able to print username and email but department is coming empty.
Firstly, you have the wrong relationship. There is a one-to-one relationship between User and UserProfile; a user can only have one profile, and a profile can only belong to one user. The way you have it now, a user can have many profiles, which doesn't make sense.
You should replace the ForeignKey with a OneToOneField.
Once you have done that, you will be able to access the profile data via the relationship: user.userprofile.department, and so on.

Django admin interface: Invalid password format or unknown hashing algorithm

I've made a register and login function which saves a user data to the database using the django User object. But when i register a user, the password linked to the user doesn't get hashed properly. This means that i have this error in the django admin interface: "Invalid password format or unknown hashing algorithm.". I've made sure to use the set_password.
models.py
from django.db import models
from django.contrib.auth.models import User
class User_Information(models.Model):
# Links UserProfile to a User model instance
user = models.OneToOneField(User)
# Override the __unicode__() method to return username
def __unicode__(self):
return self.username
forms.py
from django import forms
from django.contrib.auth.models import User
from authentication.models import User_Information
class User_Form(forms.ModelForm):
# Using the PasswordInput widget to hide the entered content of the password field
password = forms.CharField(widget=forms.PasswordInput())
# Define the nested class. The default fields can be edited here, if you wish to exclude something.
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email', 'password')
views.py
def register(request):
context = RequestContext(request)
# Checks if registration was successful. Changes to true if this is the case
# Processing form data.
if request.method == 'POST':
user_form = User_Form(data=request.POST)
# If the form is valid.
if user_form.is_valid():
# Saves the user's data to the database.
user = user_form.save()
# Hash the password and updates the user object.
user.set_password(user.password)
user.save
# Tell the template that registration was successful
messages.success(request, 'You registered successfully')
else:
print user_form.errors
else:
user_form = User_Form()
return render_to_response(
'authentication/register.html',
{'user_form': user_form},
context)
Thanks in advance.
It is possible to extend predefined form django.contrib.auth.forms.UserCreationForm to your needs.

Is there a example in django 1.6 and python 3 to build a accounts app (include:register , login , and logout )

I do have read the offical document, but it describes every facility separately, after reading
'User authentication in Django' ,'First steps' , 'The model layer', 'The view layer' and 'The template layer' and 'Forms' , I still donot know how to create a account system.
there seems no django 1.6 and python 3 built account app source code or tutorial. where can I get them, thanks.
update:
All I what is a account app which I can plug it into any new project. Its urls will look like this:
accounts/register (the form class of this page is created from the class User in django.contrib.auth)
accounts/login
accounts/logout
accounts/profile (the form class of this page is created from the model which has a field OneToOneField(User))
In your views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth import authenticate, login, logout
from django.core.context_processors import csrf
#Import a user registration form
from YourApp.forms import UserRegisterForm
# User Login View
def user_login(request):
if request.user.is_anonymous():
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
#This authenticates the user
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
#This logs him in
login(request, user)
else:
return HttpResponse("Not active")
else:
return HttpResponse("Wrong username/password")
return HttpResponseRedirect("/")
# User Logout View
def user_logout(request):
logout(request)
return HttpResponseRedirect('/')
# User Register View
def user_register(request):
if request.user.is_anonymous():
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid:
form.save()
return HttpResponse('User created succcessfully.')
else:
form = UserRegisterForm()
context = {}
context.update(csrf(request))
context['form'] = form
#Pass the context to a template
return render_to_response('register.html', context)
else:
return HttpResponseRedirect('/')
In your forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class UserRegisterForm(UserCreationForm):
class Meta:
model = User
fields = ('first_name', 'last_name', 'email', 'username', 'password1', 'password2')
In your urls.py:
# Accounts urls
url(r'accounts/login/$', 'YourApp.views.user_login'),
url(r'accounts/logout/$', 'YourApp.views.user_logout'),
url(r'accounts/register/$', 'YourApp.views.user_register'),
At last, in register.html:
<form action="/accounts/register/" method="POST"> {% csrf_token %}
<h2>Please enter your details . . .</h2>
{{ form.as_p }}
<input type="submit" value="Sign Up">
</form>
Hope this helps.