Create User Specific Objects in Django - python

Ive been trying to create a django project that has users and those users can add titles of books they have created. Only the user will be able to view the titles of his books. I was wondering how can I create a class in models.py, forms.py, & views.py that will tie the user and the titles of their books together. Here is what I have so far.
models.py
from django.db import models
from django.contrib.auth.models import User
class Scripter(models.Model):
user = models.OneToOneField(User)
name = models.CharField(max_length=30)
def __unicode__(self):
return self.name
class Title(models.Model):
author = models.ForeignKey(Scripter)
def __unicode__(self):
return self.script_title
forms.py
from django import forms
from django.contrib.auth.models import User
from django.forms import ModelForm
from scripters.models import Scripter, Title
class RegistrationForm(ModelForm):
username = forms.CharField(label=(u'User Name'))
email = forms.EmailField(label=(u'Email Address'))
password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False))
password1 = forms.CharField(label=(u'Verify Password'), widget=forms.PasswordInput(render_value=False))
class Meta:
model = Scripter
exclude = ('user',)
def clean_username(self):
username = self.cleaned_data['username']
try:
User.objects.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError("User Name has been taken!")
def clean(self):
if self.cleaned_data['password'] != self.cleaned_data['password1']:
raise forms.ValidationError("The passwords did not match")
else:
return self.cleaned_data
class LoginForm(forms.Form):
username = forms.CharField(label=(u'Username'))
password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False))
class CreateScript(ModelForm):
title = forms.CharField(label=(u'Script Title'))
class Meta:
model = Title
def clean_title(self):
title = self.cleaned_data['title']
return title
views.py
from django.http import HttpResponseRedirect
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.shortcuts import render_to_response
from django.template import RequestContext
from scripters.forms import RegistrationForm, LoginForm, CreateScript
from scripters.models import Scripter, Title
from django.contrib.auth import authenticate, login, logout
def ScripterRegistration(request):
if request.user.is_authenticated():
return HttpResponseRedirect('/profile/')
if request.method =='POST':
form = RegistrationForm(request.POST)
if form.is_valid():
user = User.objects.create_user(username=form.cleaned_data['username'],
email = form.cleaned_data['email'],
password = form.cleaned_data['password']
)
user.save()
scripter = Scripter(user=user, name=form.cleaned_data['name'])
scripter.save()
return HttpResponseRedirect('/profile/')
else:
return render_to_response('index.html', {'form': form}, context_instance=RequestContext(request))
else:
form = RegistrationForm()
context = {'form': form}
return render_to_response('index.html', context, context_instance=RequestContext(request))
#login_required
def Profile(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/login/')
Scripter = request.user.get_profile
context = {'Scripter': Scripter}
return render_to_response('profile.html', context, context_instance=RequestContext(request))
def LoginRequest(request):
if request.user.is_authenticated():
return HttpResponseRedirect('/profile/')
if request.method == 'POST':
submit = LoginForm(request.POST)
if submit.is_valid():
username = submit.cleaned_data['username']
password = submit.cleaned_data['password']
scripter = authenticate(username=username, password=password)
if scripter is not None:
login(request, scripter)
return HttpResponseRedirect('/profile/')
else:
return HttpResponseRedirect('/login/')
else:
submit = LoginForm()
context = {'submit': submit}
return render_to_response('login.html',context, context_instance=RequestContext(request))
def LogoutRequest(request):
logout(request)
return HttpResponseRedirect('/login/')
#login_required
def NewScript(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/login/')
if request.method =='POST':
title_form = CreateScript(request.POST)
if title_form.is_valid():
title = User.objects.get_or_create(
Title = title_form.cleaned_data['title'],
)
title.save()
script = Title(script_title=title_form.cleaned_data['title'])
script.save()
return HttpResponseRedirect('/edit/')
else:
return render_to_response('NewScript.html', {'title_form': title_form}, context_instance=RequestContext(request))
else:
title_form = CreateScript()
context = {'title_form': title_form}
return render_to_response('NewScript.html', context, context_instance=RequestContext(request))

I think what you're asking is how do I get the list of titles that are owned by a specific user.
This is rather easy using a reverse relationship:
scripter.title_set.all()
Will get you all the books owned by an instance of Scripter.

Related

How can I save the username in the database as an email?>

I want a signup page with 3 fields (email, password and repeat password). My goal is that when the user enters the email address, it is also saved in the database as a username. I would be super happy if someone could help me, I've been sitting for x hours trying to solve this problem. Thanks very much!
model.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
email_confirmed = models.BooleanField(default=False)
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
forms.py
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
# Sign Up Form
class SignUpForm(UserCreationForm):
# first_name = forms.CharField(max_length=30, required=False, help_text='Optional')
# last_name = forms.CharField(max_length=30, required=False, help_text='Optional')
email = forms.EmailField(max_length=254, help_text='Enter a valid email address')
class Meta:
model = User
fields = [
'username',
'password1',
'password2',
]
views.py
from django.contrib import messages
from django.contrib.auth.models import Group
from django.contrib.sites.shortcuts import get_current_site
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.template.loader import render_to_string
from .token import AccountActivationTokenGenerator, account_activation_token
from django.shortcuts import render, redirect
from .forms import *
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth import get_user_model, login
from django.utils.http import urlsafe_base64_decode
from django.views.generic import View, UpdateView
from django.contrib.auth.decorators import login_required
from .decorators import *
from django.urls import reverse_lazy
from django.utils.encoding import force_str
#unauthenticatedUser
def Example_login(request):
if request.method == 'POST':
email = request.POST.get('email')
password = request.POST.get('password')
user = authenticate(request, username=email, password=password)
if user is not None:
login(request, user)
return redirect('Example_dashboard')
else:
messages.info(request, 'Username OR password is incorrecct')
context = {}
return render(request, 'accounds/templates/Example_login.html', context)
def reset_passwrd(request):
return render(request, "reset_password.html")
#login_required(login_url='login')
def Example_dashboard(request):
form = MembersForm()
current_user = request.user
name = current_user.username.split(".")[0]
context = {'form': form, "cunrrent_user": name}
return render(request, 'example_dashboard.html', context)
def Login(request):
if request.method == 'POST':
email = request.POST.get('Benutzername')
password = request.POST.get('Passwort')
user = authenticate(request, username=email, password=password)
if user is not None:
login(request, user)
return redirect('Example_dashboard')
else:
messages.info(request, 'Username OR password is incorrecct')
return render(request, "login.html")
def logoutUser(request):
logout(request)
return redirect('login')
def registrierung(request):
return render(request, "registrierung.html")
#unauthenticatedUser
def Example_register(request):
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
user = form.save()
#username = form.cleaned_data.get('usernname')
group = Group.objects.get(name='studends')
user.groups.add(group)
messages.success(request, 'Account was created' )
return redirect('login')
contex = {'form' : form}
return render(request, 'exampl_register.html',contex)
# Sign Up View
class SignUpView(View):
form_class = SignUpForm
template_name = 'signup.html'
def get(self, request, *args, **kwargs):
form = self.form_class()
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False # Deactivate account till it is confirmed
user.save()
current_site = get_current_site(request)
subject = 'Activate Your MySite Account'
message = render_to_string('account_activation_email.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
})
user.email_user(subject, message)
messages.success(request, ('Please Confirm your email to complete registration.'))
return redirect('login')
return render(request, self.template_name, {'form': form})
class ActivateAccount(View):
def get(self, request, uidb64, token, *args, **kwargs):
try:
uid = force_str(urlsafe_base64_decode(uidb64))
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):
user.is_active = True
user.profile.email_confirmed = True
user.save()
login(request, user)
messages.success(request, ('Your account have been confirmed.'))
return redirect('login')
else:
messages.warning(request, ('The confirmation link was invalid, possibly because it has already been used.'))
return redirect('login')
I Need your help
If you want to use email instead of the default username, you have to overwrite the default User model with the custom one
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
class User(AbstractBaseUser, PermissionsMixin):
# Use the email for logging in
email = models.EmailField(max_length=254, unique=True)
USERNAME_FIELD = 'email'

Hash a password field outside of the User model - Django

I am trying to have a user register, and then log in. Once they are logged in they specify their WiFi name, followed by a wifi password, and their choice of a VPN. The problem I am having is hashing the wifi_password field upon saving it to the database. I am trying to hash the password within the edit function in views.py. I have posted the entirety of my models, forms, and views. The code is still sloppy, and will need some cleaning up when I can achieve functionality. Thanks.
models.py
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
vpn_choices = [
('openvpn', 'Open VPN'),
('pia', 'Private Internet Access'),
('expressvpn', 'Express VPN'),
]
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,
on_delete = models.CASCADE,
null = True)
wifi = models.CharField(max_length = 128)
wifi_password = models.CharField(max_length = 128)
vpn_choice = models.CharField(max_length = 20, choices = vpn_choices)
def __str__(self):
return f'self.user.username {self.user.username}'
forms.py
from django import forms
from django.contrib.auth.models import User, AbstractUser
from django.contrib.auth import get_user_model
from server.models import Profile
from django.forms import ModelForm
vpn_choices = [
('openvpn', 'Open VPN'),
('pia', 'Private Internet Access'),
('expressvpn', 'Express VPN'),
]
class LoginForm(forms.Form):
username = forms.CharField(max_length = 126)
password = forms.CharField(max_length = 126, widget = forms.PasswordInput)
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(label = 'Password',
widget = forms.PasswordInput)
password2 = forms.CharField(label = 'Repeat Password',
widget = forms.PasswordInput)
class Meta:
model = User
fields = ('username',)
def clean_password2(self):
cd = self.cleaned_data
if cd['password'] != cd['password2']:
raise forms.ValidationError('Passwords don\'t match.')
return cd['password2']
class ProfileEditForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('wifi', 'wifi_password', 'vpn_choice')
labels = {
'wifi': ('WiFi'),
'wifi_password': ('WiFi Password'),
'vpn_choice': ('VPN Choice'),
}
widgets = {
'wifi_password': forms.PasswordInput
}
views.py
from django.shortcuts import render, redirect, reverse
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponse, HttpResponseRedirect
from .forms import LoginForm, UserRegistrationForm, ProfileEditForm
from django.contrib.auth.decorators import login_required
from server.models import Profile
from django.contrib.auth.hashers import make_password
def user_login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(request,
username = cd['username'],
password = cd['password'])
if user is not None:
if user.is_active:
login(request, user)
return HttpResponse('Authenticated '\
'successfully')
else:
return HttpResponse('Disabled account')
else:
return HttpResponse('Invalid Login')
else:
form = LoginForm()
return render(request, 'login.html', {'form': form})
def index(request):
return render(request, 'index.html')
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
# Create a new user object but avoid saving it yet
new_user = user_form.save(commit = False)
# Set the chosen password
new_user.set_password(
user_form.cleaned_data['password'])
# Save the User object
new_user.save()
# Create the user profile
Profile.objects.create(user = new_user)
return render(request,
'register_done.html',
{'new_user': new_user})
else:
user_form = UserRegistrationForm()
return render(request,
'register.html',
{'user_form': user_form})
#login_required
def user_logout(request):
logout(request)
return HttpResponseRedirect(reverse('index'))
#login_required
def edit(request):
if request.method == 'POST':
profile_form = ProfileEditForm(instance = request.user.profile,
data = request.POST)
if profile_form.is_valid():
settings = profile_form.save(commit = False)
password = make_password('wifi_password')
settings.save()
else:
profile_form = ProfileEditForm()
return render(request, 'edit.html',
{'profile_form': profile_form})
But if you will hash the password yourself, you will need to override authenticate as well as the Django won't be able to regenerate the hash to find the user record

How do I show model field values in HTML page, in Django for this particular case?

I need to display the details of the user on the profilepage. But in the following situation, I am unable to render phone number and flag(attributes of SpecialUser model) on my profile page. I was asked to implement an extended model for the User model in Django auth for an application. I introduced 2 new fields i.e, phonenumber(charfield), flag(booleanfield). My form is able to take both the inputs. But I couldn't render these values again into my HTML file. Could someone help me out!
models.py
# accounts.models.py
from django.db import models
from django.contrib.auth.models import User
class SpecialUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
flag = models.BooleanField(verbose_name="Special User", default=False)
phonenumber = models.CharField(max_length=10, verbose_name="phonenumber")
def __str__(self):
return self.user.username
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import SpecialUser
class RegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ["username", "email", "password1", "password2"]
class SuperUserForm(forms.ModelForm):
class Meta:
model = SpecialUser
fields = ["flag", "phonenumber"]
views.py
from accounts.models import SpecialUser
from django.shortcuts import render, redirect
from .forms import RegisterForm, SuperUserForm
from django.contrib import messages
from django.contrib.auth.models import auth
def register(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
sp_form = SuperUserForm(request.POST)
if form.is_valid() and sp_form.is_valid():
user = form.save()
sp_form = sp_form.save(commit=False)
sp_form.user = user
sp_form.save()
messages.success(request, 'Account created!')
return redirect('login')
else:
form = RegisterForm(request.POST)
sp_form = SuperUserForm(request.POST)
messages.warning(request, 'Your account cannot be created.')
return render(request, 'register.html', {'form': form, 'sp_form': sp_form})
def login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
data = SpecialUser.objects.all()
dt = {"all": data}
return render(request, "profilepage.html", dt)
else:
messages.info(request, 'invalid credentials')
return redirect('login')
else:
return render(request, 'login.html')
def logout(request):
auth.logout(request)
return redirect('login')
profilepage.html
<h1>{{user.username}}</h1>
<h4>Email : {{user.email}}</h4>
<h5>Phone Number : {{all.phonenumber}}</h5>
{%if user.flag %}
<button>Special User</button>
{%endif%}
here is the correct html you need to see your data
{%for d in all%}
{%ifequal d.user user%}
<h1>{{d.user.username}}</h1>
<h4>Email : {{d.user.email}}</h4>
<h5>Phone Number : {{d.phonenumber}}</h5>
{%if d.flag %}
<button>Special User</button>
{%endif%}
{%endifequal%}
{%endfor%}

Password mismatch in registration form that inherits from UserCreationForm

I have a form that inherits from the UserCreationForm. The file looks like this:
from django import forms
from django.contrib.auth import password_validation
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User, Group
from main.models.users import MyUser
class MyUserCreationForm(UserCreationForm):
email = forms.EmailField(required=True)
group = forms.CharField(max_length=50, required=True)
class Meta:
model = MyUser
fields = ("group", "email", "username", "email", "password1", "password2")
def save(self, commit=True):
user = super(MyUserCreationForm, self).save(commit=False)
user.email = self.cleaned_data["email"]
if commit:
user.save()
return user
For some reason, when trying to fill up the form, I get a password mismatch error like so:
ERROR - {'password_mismatch': "The two password fields didn't match."}
I tried overriding the clean_password1 and clean_password2 with no help. Code:
def clean_password1(self):
password1 = self.cleaned_data.get('password1')
try:
password_validation.validate_password(password1, self.instance)
except forms.ValidationError as error:
# Method inherited from BaseForm
self.add_error('password1', error)
return password1
Any ideas why this is happening? Why is it thinking that both of my passwords are not identical? I'm sure they are, as I tried a million times and even copy and pasted.
view:
def register(request):
if request.method == 'POST':
form = MyUserCreationForm(request.POST)
if form.is_valid():
print(f"Valid form. Choosen group: {form.cleaned_data.get('group')}")
user = form.save()
group = Group.objects.get(name=form.cleaned_data.get('group'))
user.groups.add(group)
login(request, user)
messages.success(request, f"Thanks, {form.cleaned_data.get('username')}, "
f"for signing up as a {form.cleaned_data.get('group')} ")
return redirect('main:homepage')
else:
logger.error(form.error_messages)
for msg in form.error_messages:
messages.error(request, f'{msg}: {form.error_messages[msg]}')
return render(request,
template_name='main/register.html',
context={'form': form})
else:
form = MyUserCreationForm()
return render(request,
template_name='main/register.html',
context={'form': form})
i am not sure about code but you can try this
from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render, redirect
def signup(request):
if request.method == 'POST':
#inhereting Usercreation form
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
#validating the password match while creating the user.
username = form.cleaned_data.get('username')
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password)
login(request, user)
return redirect('home')
else:
form = UserCreationForm()
return render(request, 'signup.html', {'form': form})

Attribute user.grade cannot be referenced in Django template

I have some code for a website that I'm building.
in my views.py, i have the following code:
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from django.conf.urls import url
from .models import UserInfo, Events
from django import forms
from .forms import RegisterForm, LoginForm, OrderForm
from django.contrib.auth.models import User
from django.shortcuts import redirect
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth import authenticate, login, logout
# Create your views here.
def home(request):
return render(request, 'student/index.html')
#csrf_exempt
def signin(request):
print "login"
if request.method == 'POST':
form = LoginForm(request.POST)
username = request.POST['username']
password = request.POST['password']
print "input username ", username
try:
if form.is_valid():
user = authenticate(username=username, password=password)
if user is not None:
print "user not none"
print user.username
print user.email
login(request,user)
return redirect("/")
else:
print "login failed"
raise forms.ValidationError({'username':['Invalid username/password']})
else:
print form.errors
except:
raise
else:
print "hello"
form = LoginForm()
return render(request, 'student/login.html', {'form': form})
#csrf_exempt
def signup(request):
print "signup"
if request.method == 'POST':
print "post signup"
form = RegisterForm(request.POST)
try:
if form.is_valid():
print form.cleaned_data
u = User.objects.create_user(form.cleaned_data['emailid'], form.cleaned_data['emailid'], form.cleaned_data['passwd1'] )
ui = UserInfo()
ui.user = u
ui.class_of = form.cleaned_data['gradyear']
ui.grade = form.cleaned_data['grade']
ui.balance = 0
ui.save()
user = authenticate(username=form.cleaned_data['emailid'], password=form.cleaned_data['passwd1'])
login(request,user)
print "after login in signup"
return redirect("/")
else:
print "error"
print form.errors
except:
raise
print "error here"
print form.errors
pass
#return render(request, 'student/register.html', {'form': form})
else:
form = RegisterForm()
return render(request, 'student/register.html', {'form': form})
def forgotpassword(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
print form.cleaned_data
return HttpResponseRedirect('/thanks/')
else:
print "INVALID"
print form.errors
else:
form = LoginForm()
return render(request, 'student/forgotpassword.html')
def studentinfo(request):
return render(request, 'student/studentinfo.html', {} )
def error(request):
return render(request, 'student/LoginError.html', {} )
def site_logout(request):
logout(request)
return redirect("/")
#return render(request, 'student/studentinfo.html', {} )
def order(request):
if request.method == 'POST':
form = 0
return render(request, 'student/orderform.html')
def dashboard(request):
user = request.user
return render(request, 'student/dashboard.html', {'user': user})
def blog(request):
return render(request, 'student/blog.html')
and this is my models.py, where UserInfo is:
from django.db import models
from django.contrib.auth.models import User
class UserInfo(models.Model):
user = models.ForeignKey(User)
class_of = models.IntegerField()
#username = user.username
#fname = user.first_name
#lname = user.last_name
#email = user.email
#Staff = user.is_staff
pub_date = models.DateTimeField( auto_now=True)
grade = models.IntegerField()
balance = models.DecimalField(max_digits=6, decimal_places=2)
class Events(models.Model):
name = models.CharField(max_length = 80)
date = models.DateTimeField()
cost = models.DecimalField(max_digits = 6, decimal_places = 2)
def __unicode__(self):
return str(self.name)
# Create your models here.
in my HTML code using the Django template language, {{ user.username }} and {{ user.email }} show up perfectly, but why won't {{ user.grade }} work the same way?
grade is not an attribute of Django's User model but is an attribute of UserInfo, you need need to use something like:
{{ user.user_infos.grade }}
Where user_infos is the related_name in your model (it should be OneToOneField right?):
user = models.OneToOneField(User, related_name='user_infos')

Categories