Django save user profile manually - python

I have created a Profile and attached to user model using OneToOneField. I have a registration form where user enters input which corresponds to user and profile. Django provides User.objects.create_user to save fields which are related to User model, but i don't know how to save details of Profile model manually.
Here is my code:
models.py
from django.db import models
from django.contrib.auth.models import User
def Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
full_name = models.CharField(max_length=150, required=True)
# lot more fields here
views.py
#csrf_protect
def register(request):
if request.method == 'POST':
full_name = request.POST.get('full_name', '')
username = request.POST.get('username', '')
password = request.POST.get('password', '')
User.objects.create_user(username=username, password=password)
# how to save Profile full_name here
return render(request, 'register.html')
register.html
<form method="post" action="/register/">{% csrf_token %}
<div class="form-group">
<label for="full_name">Name</label>
<input type="text" name="full_name" id="full_name">
</div>
<div class="form-group">
<label for="username">Username</label>
<input type="text" name="username" value="" id="username">
</div>
<div class="form">
<label for="password">Password</label>
<input type="pass" name="password" value="" id="password">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
1) How can i save full_name of Profile model in views.py ? Can I do this without creating form class for every model in the future that want to save or Signals?
2) Do I need to change auth_user_model in settings.py in order to save profile details manually?
3) How to validate the fields without creating a new Form class?

#csrf_protect
def register(request):
if request.method == 'POST':
full_name = request.POST.get('full_name', '')
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = User.objects.create_user(username=username, password=password)
Profile.objects.create(user=user,full_name=full_name)
# how to save Profile full_name here
return render(request, 'register.html')
you can use the created user instance to create the profile associated with that user

Related

Django form errors not showing when use id_<field-name>

I'm a beginner in Django, I try to use for="id_<field-name>" method to create a signup form interface, but the default validation like "This field is required." or "This username already exists" is not showing. I don't want to use {{ form.as_p }} because I want to separate the field. The registration still working if i input the true the valid things.
HTML
<form method="POST" class="register-form" id="register-form" enctype="multipart/form-data" >
{% csrf_token %}
<div class="form-group">
<label for="id_username"><i class="zmdi zmdi-account material-icons-name"></i></label>
<input type="text" name="username" id="username" placeholder="Username"/>
</div>
<div class="form-group">
<label for="id_email"><i class="zmdi zmdi-email"></i></label>
<input type="email" name="email" id="email" placeholder="Your Email" />
</div>
<div class="form-group">
<label for="id_password"><i class="zmdi zmdi-lock"></i></label>
<input type="password" name="password" id="password" placeholder="Password"/>
</div>
<div class="form-group">
<input type="checkbox" name="agree-term" id="agree-term" class="agree-term" />
<label for="agree-term" class="label-agree-term"><span><span></span></span>I agree all statements in Terms of service</label>
</div>
<div class="form-group form-button">
<input type="submit" name="signup" id="signup" class="form-submit" value="Register"/>
</div>
</form>
views.py
def register(request):
registered = False
if request.method == 'POST':
# Get info from "both" forms
# It appears as one form to the user on the .html page
user_form = UserForm(data=request.POST)
profile_form = UserProfileInfoForm(data=request.POST)
# Check to see both forms are valid
if user_form.is_valid() and profile_form.is_valid():
# Save User Form to Database
user = user_form.save()
# Hash the password
user.set_password(user.password)
# Update with Hashed password
user.save()
# Now we deal with the extra info!
# Can't commit yet because we still need to manipulate
profile = profile_form.save(commit=False)
# Set One to One relationship between
# UserForm and UserProfileInfoForm
profile.user = user
# Check if they provided a profile picture
if 'profile_pic' in request.FILES:
print('found it')
# If yes, then grab it from the POST form reply
profile.profile_pic = request.FILES['profile_pic']
# Now save model
profile.save()
# Registration Successful!
registered = True
else:
# One of the forms was invalid if this else gets called.
print(user_form.errors,profile_form.errors)
else:
# Was not an HTTP post so we just render the forms as blank.
user_form = UserForm()
profile_form = UserProfileInfoForm()
# This is the render and context dictionary to feed
# back to the registration.html file page.
return render(request,'basic_app/registration.html',
{'user_form':user_form,
'profile_form':profile_form,
'registered':registered,
})
forms.py
from django import forms
from django.contrib.auth.models import User
from .models import UserProfileInfo, TeaProfileInfo
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = User
fields = ('username','email','password')
My signup page interface
A quick way to validate your form by adding the following to your form.py
def clean(self):
super(UserForm, self).clean()
username = self.cleaned_data.get('username')
email = self.cleaned_data.get('email')
password = self.cleaned_data.get('password')
if username == "" or email == "" or password == "":
raise forms.ValidationError(['This field is required.'])
In your HTML make sure to add the following after/before each field
{{ username.errors }}
{{ email.errors }}
{{ password.errors }}

Registration Form not saving data in Profile Model, using extended Django User model

Recently i am facing a problem in registration. I have made a ** accounts** app in my project for registrations. I don't want to save data in default **User** model in dB. So I have extended **User** model with **OneToOne** relationship with **Profile** model and trying to save the data into "Profile" model but when I submitting the form I don't get any error but data don't save in "Profile" DB.
here is my models.py where I make OneToOne Relationship with default "User" model.
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone=models.CharField(max_length=20)
address=models.CharField(max_length=150)
def __str__(self):
return self.user.username
I am trying to make ProfileForm form and InfoProfileForm form here to get the form data in forms.py.
from django import forms
from django.contrib.auth.models import User
from .models import Profile
from django.contrib.auth.forms import ReadOnlyPasswordHashField
class ProfileForm(forms.ModelForm):
password = forms.CharField(max_length=20, widget=forms.PasswordInput)
#form = ProfileForm(data=request.POST, user=request.user)
class Meta:
model = User
fields=('username','email','password')
#extra info
class InfoProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('phone','address')
Here is my Views.py where I am trying to merge two models (default User model and Profile model)
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
# Create your views here.
from .forms import ProfileForm,InfoProfileForm
from django.http.response import HttpResponse
def registration(request):
if request.method == 'POST':
profile_form = ProfileForm(request.POST)
info_form = InfoProfileForm(request.POST)
if profile_form.is_valid() and info_form.is_valid():
user = profile_form.save(commit=True)
user.set_password(user.password)
user.save()
profile=info_form.save(commit=False)
profile.user = user
profile.phone = user.cleaned_data["phone"]
profile.address = user.cleaned_data["address"]
profile.save()
print('submittef')
else:
HttpResponse("<h1>something wrong</h1>")
else:
profile_form = ProfileForm(request.POST)
info_form = InfoProfileForm(request.POST)
return render(request, 'accounts/registration.html',{'profile_form': profile_form,'info_form': info_form,})
here is my HTML template
<form action="{% url 'registration' %}" method="POST">
{% csrf_token %}
<div class="container">
<h1>Register</h1>
<p>Please fill in this form to create an account.</p>
<hr>
<label for="name"><b>Name</b></label>
<input type="text" placeholder="Enter Name" name="user" required>
<label for="email"><b>Email</b></label>
<input type="text" placeholder="Enter Email" name="email" required>
<label for="phone"><b>Phone</b></label>
<input type="text" placeholder="Enter Phone" name="phone" required>
<label for="address"><b>Address</b></label>
<input type="text" placeholder="Enter Phone" name="address" required>
<label for="password"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="password"required>
<label for="password2"><b>Repeat Password</b></label>
<input type="password" placeholder="Repeat Password" name="password2" required>
<hr>
<button type="submit" class="registerbtn">Register</button>
</div>
</form>
May be try referencing the profile model from the user since it's a one to one field
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
# Create your views here.
from .forms import ProfileForm,InfoProfileForm
from django.http.response import HttpResponse
def registration(request):
if request.method == 'POST':
profile_form = ProfileForm(request.POST)
info_form = InfoProfileForm(request.POST)
if profile_form.is_valid() and info_form.is_valid():
user = profile_form.save(commit=True)
user.set_password(user.password)
user.profile.phone = user.cleaned_data["phone"]
user.profile.address = user.cleaned_data["address"]
user.save()
print('submitted')
else:
HttpResponse("<h1>something wrong</h1>")
else:
profile_form = ProfileForm(request.POST)
info_form = InfoProfileForm(request.POST)
return render(request, 'accounts/registration.html',{'profile_form':profile_form,'info_form': info_form,})

Django 2.1.4 Registration Form + Login Page

Hi I am new to Django and need help with registration form and login. I am able to register and able to see the user credentials registered under admin register model. However, i tried to take the user-credentials in the database and then want to do a login, but unable to do so. Can someone help please.
models.py
class register(models.Model):
name = models.CharField(max_length=250)
username = models.CharField(max_length=20)
password = models.CharField(max_length=20)
occupation = models.CharField(max_length=100)
def __unicode__(self):
return str(self.username)
Views.py
#register
def registerForm(request):
if request.method == 'POST':
if request.POST.get('name') and request.POST.get('username') and request.POST.get('password') and request.POST.get('occupation'):
reg = register()
reg.name = request.POST['name']
reg.username = request.POST['username']
reg.password = request.POST['password']
reg.occupation = request.POST['occupation']
reg.save()
return render(request, 'login.html')
else:
return render(request, 'register.html')
#Login
def Login(request):
if request.method == 'POST':
if request.POST.get('username') and request.POST.get('password'):
usr_login = register()
usr_login.username = request.POST['username']
usr_login.password = request.POST['password']
usr_login.user = authenticate(username=username, password=password)
if usr_login.user:
login(request, usr_login.user)
return HttpResponseRedirect('/forum/')
else:
error = "Username and Password are invalid. Please try again."
return render(request, 'login.html')
else:
return render(request, 'login.html')
login.html
<form method="post" action="/forum/">
{% csrf_token %}
<div class="form-group">
<label for="username">Username:</label>
<input type="username" class="form-control" id="username" placeholder="Enter username" required="required">
</div>
<div class="form-group">
<label for="pwd">Password:</label>
<input type="password" class="form-control" id="pwd" placeholder="Enter password" required="required">
</div>
<div class="row">
<div class="col" align="center">
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox"> Remember me
</label>
</div>
<button type="submit" class="btn btn-primary" value="login">Submit</button><br><br>
Not yet registered? Register Here.
</form>
urls.py
# login
url(r'^login/$', views.Login, name='login'),
# register
url(r'^registeration/$', views.registerForm, name='registeration'),
You are trying to authenticate the user using the django builtin authentication backend but you are not using the django User model. In your case you have to create custom authentication logic. I strongly suggest you to hash the user's password.
If you want to use the builtin auth framework you check out the documentation for more information https://docs.djangoproject.com/en/2.1/ref/contrib/auth/

Django: invalid form

I am new to Django and is currently trying to make a user registration form for my application. Does anyone know why form.is_valid() is returning False?
forms.py
class RegistrationForm(forms.ModelForm):
username = forms.CharField(widget=forms.TextInput)
password = forms.CharField(widget=forms.PasswordInput)
email = forms.CharField(widget=forms.EmailInput)
class Meta:
model = User
fields = ['username', 'password', 'email']
views.py
def registration(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
print "valid"
username = form.cleaned_data['username']
email = form.cleaned_data['email']
password = form.cleaned_data['password']
User.objects.create_user(username=username, email=email, password=password)
user = authenticate(username=username, passsword=password)
if user is not None:
login(request, user)
return redirect('/admin')
else:
# return a blank form
print "invalid"
return render(request, 'registration/register.html', {'form': form})
register.html
<div class="container ">
<form method="post" action=".">
{% csrf_token %}
<h2 class="form-signin-heading">Register</h2>
<input type="text" id="inputUsername" class="form-control" placeholder="Username" required autofocus>
<input type="password" id="inputPassword" class="form-control" placeholder="Password" required>
<input type="email" id="inputEmail" class="form-control" placeholder="Email" required autofocus>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
I see that you defined the form in the view, but you are not using it inside the template (register.html). I would have done something more like this:
<div class="container">
<h2 class="form-signin-heading">Register</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign Up</button>
</form>
</div>
Also, if you haven't noticed, your "return render(...)" line is within the else block. And while not necessary, I think it's good practice to define context as a dict and pass it in using context=context in the view or whatever you name it. However, for the case you have here, I'd suggest using a class-based view. It's much cleaner for signing a user up.
from django.views.generic import CreateView
from django.urls import reverse_lazy
class Registration(CreateView):
form_class = RegistrationForm
template_name = 'register.html'
success_url = reverse_lazy('login')
# in the urls.py, set name='login' for the login page
# signing a user up will not grant admin priveleges, that is only done through the
# creation of a super user or if you coded your model to do so (not recommended)
and as for any validation, look into creating a clean(self) method inside the forms.py Like this:
# this will be on the same block as class Meta you defined
# ensures no other user has the username with a different case
def clean(self):
cleaned_data = super(RegistrationForm, self).clean()
username = cleaned_data.get('username')
email = cleaned_data.get('email')
# checks if username is provided and ensures the username is not already in use
if username and User.objects.filter(username__iexact=username).exists():
self.add_error('username', 'A user with that username already exists.')
# checks if email is provided and ensures this email is not already in use
if email and User.objects.filter(email__iexact=email).exists():
self.add_error('email', 'That email address is already in use.')
return cleaned_data
I saw that you were setting some labels in your template, this can be done within the forms.py on the same block as the class Meta and def clean(self) I just provided:
# method to overwrite the form label names
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].label = 'Username'
self.fields['email'].label = 'Email Address'
I have not tested this, I'm going off of memory but I think this is a route similar to your use case, and it's utilizing the Django resources available to you :) Good Luck and I hope this helps!
P.S: You should look into django-crispy-forms since you're using bootstrap.
You haven't given any of your HTML input elements a name attribute. Without that, the browser can't send any data to the server.
Note that if you had used Django itself to produce the fields, they would not only include the name, but would also be populated when the invalid form was redisplayed.

Django not authenticating using custom User model

I am trying to authenticate users against an existing database. I can authenticate the user with their email and password combination but I cannot save the authorisation, meaning the user is not actually logged in.
I know this because in Template.html, it is not showing the correct options after login when I call {% if user and not user.is_anonymous %}
I believe the fault is coming from this line in views.py
auth_login(request, user)
Views.py
from django.contrib.auth import logout as auth_logout
from django.contrib.auth import login as auth_login
from django.contrib.auth import authenticate
...
def login_email(request):
if request.method == 'POST':
email = request.POST.get('email')
password = hashlib.md5(request.POST.get('password')).hexdigest()
#db query to check if email and password combination exist
user = Users.objects.get(email=email,password=password)
if user is not None:
user.backend = 'django.contrib.auth.backends.ModelBackend'
auth_login(request, user)
return redirect('/personalised')
else: #failed to return to login page
return render(request, 'login.html',{})
#invalid POST request recieved
else:
return render(request,"login.html",{})
login.html
<form action="/login_email/" method="POST">
{% csrf_token %}
<div class="form-group">
<label for="email">Email address</label>
<input type="email" name="email" class="form-control" id="email" placeholder="Email">
</div>
<div class="form-group">
<label for="email">Password</label>
<input type="password" name="password" class="form-control" id="password" placeholder="Password">
</div>
<button type="submit" class="btn btn-info">Submit</button>
</form>
Models.py
class Users(models.Model):
visitorid = models.CharField(db_column='visitorID', max_length=80) # Field name made lowercase.
name = models.CharField(max_length=255)
source = models.CharField(max_length=4)
visits = models.IntegerField()
last_visit = models.CharField(max_length=10)
email = models.CharField(max_length=255)
unsubscribe = models.CharField(max_length=1)
twitter = models.CharField(max_length=100)
password = models.TextField()
.....
template.py
{% if user and not user.is_anonymous %}
<li>My Feed </li>
<li>Trending</li>
<li>Your Saves</li>
<li>Logout </li>
{% else %}
<button type="button" class="btn btn-success navbar-btn">Sign in with Email</button>
{% endif %}
Do not use this code:
email = request.POST.get('email')
password = hashlib.md5(request.POST.get('password')).hexdigest()
#db query to check if email and password combination exist
user = Users.objects.get(email=email,password=password)
Instead use the authenticate method. It returns a User
user = authenticate(email=email, password=password)
This assumes that you have an appropriate auth backend setup.

Categories

Resources