I am creating a custom user model, here's the code in models.py:
class Users(models.Model):
username = models.CharField(max_length=30)
password = models.CharField(max_length=30)
contactnos = models.IntegerField()
address = models.CharField(max_length=50)
fname = models.CharField(max_length=30)
mname = models.CharField(max_length=30)
lname = models.CharField(max_length=30)
def __unicode__(self):
return self.username
I have this line of code in views.py
def auth_view(request):
try:
m = Users.objects.get(username=request.POST['username'])
if m.password == request.POST['password']:
request.session["id"] = m.id
myid = request.session["id"]
if myid == m.id:
return render(request, "profile.html", {
'username': m,
'myid': myid
})
else:
HttpResponse("Session has expired. Log in again.")
except Users.DoesNotExist:
return HttpResponseRedirect('/account/invalid')
The code above can check if the user is in the database and able to redirect to profile page. What I want to achieve is if the user log out, the session key should expire or redirect to another page and not on the profile page.
And I want to ask, if it is really possible? Thanks.
Just create another view for log out.
def logout_view(request):
try:
del request.session['id']
except KeyError:
pass
return HttpResponseRedirect('/home')
Related
I am working on a Django Ticketing project where I want guest to activate Ticket PIN and then register for the event they bought the ticket for. And I also want them to have login user access and be able to update profile immediately after login.
The application usually start with PIN activation and thereafter guest registration. The issue is that I don't know how to pass the PIN value from the PIN activation view to the guest registration view.
Notice that I have used request.session['pin'] = pin_value to set the PIN as the session variable in the pin activation view and got it using user_pin = request.session.get('pin') in the register guest view but only the Guest.objects.create(guest_name=new_user, pin=user_pin) in the register guest view gets the session variable while the Pin.objects.filter(value=user_pin).update(status='Activated') fails to get the session variable for the registration process to be completed. I have tried using a literal value in the Pin filter and update query and it worked but using the session variable does not.
Below are my models:
class Guest(models.Model):
guest_name = models.OneToOneField(User, on_delete=models.CASCADE, blank=True)
pin = models.CharField(max_length=6, default='No Pin', blank=True)
def __str__(self):
return f"{self.guest_name}"
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null = True)
surname = models.CharField(max_length=20, null=True)
othernames = models.CharField(max_length=40, null=True)
gender = models.CharField(max_length=6, choices=GENDER, blank=True, null=True)
phone = PhoneNumberField()
image = models.ImageField(default='avatar.jpg', blank=False, null=False, upload_to ='profile_images',
)
def __str__(self):
return f'{self.user.username}-Profile'
class Pin(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
value = models.CharField(max_length=6, default=generate_pin, blank=True)
added = models.DateTimeField(auto_now_add=True, blank=False)
reference = models.UUIDField(primary_key = True, editable = False, default=uuid.uuid4)
status = models.CharField(max_length=30, default='Not Activated')
#Save Reference Number
def save(self, *args, **kwargs):
self.reference == str(uuid.uuid4())
super().save(*args, **kwargs)
def __unicode__(self):
return self.ticket
class Meta:
unique_together = ["ticket", "value"]
def __str__(self):
return f"{self.ticket}"
def get_absolute_url(self):
return reverse("pin-detail", args=[str(self.id)])
My Views code:
def pin_activation(request):
if request.method == "POST":
#Create PIN form
form = PinActivationForm(request.POST)
#Get User Pin Value from Form
pin_value = form['pin'].value()
#Check if the the form has valid data in it
if form.is_valid():
try:
#Get user Pin with the one in the Database
check_pin_status = Pin.objects.get(value=pin_value)
except Pin.DoesNotExist:
messages.error(request, f'{pin_value} Does Not Exist')
return redirect('pin-activation')
else:
#Check PIN status
if check_pin_status:
#Get Event Ticket Date of the PIN
event_date = check_pin_status.ticket.event.date
#Get Current Date
current_date = datetime.now().date()
#Check if Event Date is Passed the Current Date
if event_date < current_date:
messages.error(request, 'Event Has Passed')
return redirect('pin-activation')
else:
#Update the User Pin with a new status of Activated
Pin.objects.filter(value=form['pin'].value()).update(status='Validated')
#Message the User
messages.success(request, 'Pin Validated Successfully')
#Redirect the user to register for seat
return redirect('register-guest')
#Check filter the DB where the PIN status is Validated
request.session['pin'] = pin_value
elif Pin.objects.filter(value=form['pin'].value(), status="Validated"):
messages.error(request, 'Pin Already Validated. Register for Seat')
return redirect('register-guest')
#Check Filter PIN in DB where Status is Activated
elif Pin.objects.filter(value=form['pin'].value(), status="Activated"):
messages.error(request, "Pin Already Activated, Login.")
return redirect('user-login')
else:
messages.error(request, 'Something Went Wrong. Try again')
else:
form = PinActivationForm()
context = {
'form':form,
}
return render(request, 'user/pin_activation.html', context)
def register_guest(request):
#get session variable
user_pin = request.session.get('pin')
form = GuestUserForm(request.POST)
page_title = "Festival Registration"
if request.method == 'POST':
form = GuestUserForm(request.POST)
pin_form = PinActivationForm(request.POST)
if form.is_valid() and pin_form.is_valid():
new_user = form.save()
Guest.objects.create(guest_name=new_user, pin=user_pin)
Pin.objects.filter(value=user_pin).update(status='Activated')
messages.success(request, 'Registered Successfully. Login')
return redirect('user-login')
else:
form = GuestUserForm()
pin_form = PinActivationForm()
context = {
'form':form,
'pin_form':pin_form,
'page_title':page_title,
}
return render(request, 'user/register.html', context)
Someone should please help with the best way of solving this problem. Thanks
you cannot save a quest as a User in this way.
Do something like this.
From youre form get the username.
Then create a new User with that username and create the Guest with that new user.
//simple form --> get it in youre template
class GuestUserForm(forms.Form):
username = forms.CharField()
password=forms.CharField()
//create new user from the form in template
user_guest = form.cleaned_data.get("username")
new_user = User.objects.create_user(username=user_guest)
//create new guest with created user
Guest.objects.create(guest_name=new_user)
//youre view function
def register_guest(request):
if request.method == 'POST':
form = GuestUserForm(request.POST)
if form.is_valid():
user_guest = form.cleaned_data.get("username")
print(user_guest)
new_user = User.objects.create_user(username=user_guest)
Guest.objects.create(guest_name=new_user)
form = GuestUserForm()
return render(request, "index.html",{"form":form})
I'm a beginner and I'm trying to create a small network project in which users can follow each other. I have implemented the follow button right, so it updates my models and displays proper info to users, but I can't get unfollow to work properly. I'm guessing it's something to do with the way I implemented follow model (with many to many field), but I'd like to implement it this way for practice... Anyhow, here's the code:
Models:
class User(AbstractUser):
pass
class Follow(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_follow")
following = models.ManyToManyField(User, blank=True, related_name="followers")
And view:
def users(request, username):
"""Displaying user profiles"""
if request.method == "POST":
user = request.user
profile = User.objects.get(username=username)
follow = Follow(user=user)
follow.save()
if "unfollow" in request.POST:
profile.followers.remove(user)
follow.following.remove(profile)
return HttpResponseRedirect(reverse('users', args=(username,)))
elif "follow" in request.POST:
follow.following.add(profile)
return HttpResponseRedirect(reverse('users', args=(username,)))
This code yields in: "ValueError at /users/test
Cannot query "admin": Must be "Follow" instance." at the profile.followers.remove(user) line...
Playing with it in shell I found out (at least I think so) that the line under it (follow.following.remove(profile) - which by the way was there before I tried with the profile.followers.remove(user)) removes the profile from Follow model, but for some reason it is not by itself updated in the Users model (for followers) ???
from django.db import models
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=40)
pwd = models.CharField(max_length=40)
def __str__(self):
return self.name
class Follow(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
another_user = models.ManyToManyField(User, related_name='another_user')
def __str__(self):
return self.user.name
============================================================================
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .models import User, Follow
# Create your views here.
def index(request):
if 'user' in request.session:
return render(request, 'index.html')
else:
return redirect('login')
def profile(request, user_name):
user_obj = User.objects.get(name=user_name)
session_user = User.objects.get(name=request.session['user'])
session_following, create = Followers.objects.get_or_create(user=session_user)
following, create = Followers.objects.get_or_create(user=session_user.id)
check_user_followers = Followers.objects.filter(another_user=user_obj)
is_followed = False
if session_following.another_user.filter(name=user_name).exists() or following.another_user.filter(name=user_name).exists():
is_followed=True
else:
is_followed=False
param = {'user_obj': user_obj,'followers':check_user_followers, 'following': following,'is_followed':is_followed}
if 'user' in request.session:
return render(request, 'profile.html', param)
else:
return redirect('index')
def follow_user(request, user_name):
other_user = User.objects.get(name=user_name)
session_user = request.session['user']
get_user = User.objects.get(name=session_user)
check_follower = Followers.objects.get(user=get_user.id)
is_followed = False
if other_user.name != session_user:
if check_follower.another_user.filter(name=other_user).exists():
add_usr = Followers.objects.get(user=get_user)
add_usr.another_user.remove(other_user)
is_followed = False
return redirect(f'/profile/{session_user}')
else:
add_usr = Followers.objects.get(user=get_user)
add_usr.another_user.add(other_user)
is_followed = True
return redirect(f'/profile/{session_user}')
return redirect(f'/profile/{session_user}')
else:
return redirect(f'/profile/{session_user}')
=============================================================================
User This For Reference...Follow And Unfollw Logic
I am a beginner in Django and I am very need your help.
Part of code:
models.py
from django.contrib.auth.models import User
class Author(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
department = models.CharField(max_length=200)
def __str__(self):
return self.user.username
class hardware(models.Model):
hostname = socket.gethostname()
login_username = getpass.getuser()
user = User.username
hardware_name = models.CharField(max_length=20)
order_no = models.CharField(max_length=10)
price = models.DecimalField(max_digits=5,decimal_places=2)
confirm = models.BooleanField(default=False)
login_user = models.ForeignKey(Author, on_delete=models.CASCADE)
computer_login_user = models.CharField(max_length=10,default=login_username)
computer = models.CharField(max_length=30,default=hostname)
def __str__(self):
return self.order_no
views.py
def get_author(user):
qs = Author.objects.filter(user=user)
if qs.exists():
return qs[0]
return None
def new_record(request):
form = OrderForm(request.POST or None, request.FILES or None)
if form.is_valid():
author = get_author(request.user)
form.instance.login_user = author
form.save()
return redirect(all_records)
context = {
'form': form
}
return render(request, 'orders/form.html', context)
I will try to explain my problem briefly.
Computers are in public places (productions) and anyone can add new record. That why in the table is info about hostname, who is login on computer and login user.
So it works well when the user is logged in to the system, but there is a problem when a new record tries to add an unlogged user (guest). Is an error "'AnonymousUser' object is not iterable".
I know that request.user is empty now.
Ok, Now questions...
How to add "guest" user and add it if noone is login?? How to add a new record if the user is not logged in??
I am sorry for very long post and Thanks for all suggestions.
So, if I understand correctly, you can do this a few ways:
The easiest way is to simply set the login_user field nullable and blank or,
Create a "guest user" and "guest author" in your Django database that is not active (is_active is set to False so they can't log in) and all anonymous users are assigned that User and Author instance the database.
As mentioned, the simplest method would be just to set the login_user field as nullable and blank, like such:
login_user = models.ForeignKey(Author, on_delete=models.CASCADE, blank=True, null=True)
And if your get_author() returns None, then simply leave that column blank, though this might affect other parts of your application if an Author or User object is required elsewhere.
Another way to do it in your get_author() method using a "guest" user:
def get_author(user):
if user.is_anonymous:
guest_user = User.objects.get(username="guest") # or whatever ID or name you use for the placeholder user that no one will be assigned
guest_author = Author.objects.get_or_create(user=guest_user)
return guest_author
else:
return Author.objects.get(user=user)
In this option, you'd need to set your department field in Author to blank and null or set a default like:
class Author(models.Model):
user = ...
department = ...(..., default="none")
or
class Author(models.Model):
user = ...
department = ...(..., blank=True, null=True)
Yet another option might be to create a new "guest" user for each action:
import random
import string
def randomString(stringLength):
letters = string.ascii_letters
return ''.join(random.choice(letters) for i in range(stringLength))
def get_author(user):
if user.is_anonymous:
random_username = f"{randomString(10)}_guest"
random_email = f"{randomString(5)}_guest#example.com"
guest_user = User.objects.create(username=random_username, is_active=False, email=random_email...)
guest_author = Author.objects.create(user=guest_user, department="none")
return guest_author
else:
return Author.objects.get(user=user)
Thank you for your help and time. I chose the second solution after little change.
def get_author(user):
if user.is_anonymous:
guest_user = User.objects.get(username="guest") # or whatever ID or name you use for the placeholder user that no one will be assigned
qs = Author.objects.filter(user=guest_user)
if qs.exists():
return qs[0]
return None
else:
qs = Author.objects.filter(user=user)
if qs.exists():
return qs[0]
return None
Now is little better and working well.
When I use exactly your method was little mistake: "ValueError: Cannot assign "(<Author: guest>, False)": "hardware.login_user" must be a "Author" instance."
So, anyway thank you again.
I trying to make auto increment of user_id after the form is filled.
It did appear in cleaned_data, but I still can't make register an account.
forms.py
class RegForm(forms.ModelForm):
password=forms.CharField(widget=forms.PasswordInput())
password_confirm = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = models.UserProfile
fields = ['user_name','password','email','birthday','address']
def clean(self):
user_id = models.UserProfile.user_id
cleaned_data = super(RegForm, self).clean()
password = cleaned_data["password"]
password_confirm = cleaned_data["password_confirm"]
if user_id == None:
self.cleaned_data['user_id'] = 1
else:
self.cleaned_data['user_id'] = models.UserProfile.objects.count() + 1
if password != password_confirm:
raise forms.ValidationError("wrong password")
return self.cleaned_data
def clean_asset_code(self):
user_name = self.cleaned_data['user_name']
if models.UserProfile.objects.filter(user_name=user_name).exists():
raise forms.ValidationError("This user_name already exist.")
return user_name
views.py
def regist(request):
if request.method == 'POST':
register_form = forms.RegForm(request.POST)
if register_form.is_valid():
register_form.save()
return HttpResponseRedirect('/')
else:
register_form = forms.RegForm()
messages.get_messages(request)
template = get_template('regist.html')
request_context = RequestContext(request)
request_context.push(locals())
html = template.render(request_context)
return HttpResponse(html)
You are trying to increase user_id before form is getting validated, I don't think that is a good idea.
To make an auto increment of user_id
What you can do is make user_id a primary key field.
Django Documentation
import uuid
from django.db import models
class UserProfile(models.Model):
user_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False,serialize=True)
In this way whenever your form passes all validity pass and when submitted the user_id is automatically incremented.
I have a form to input a user id and I want compare this id with database values (usrId).
forms.py
from django import forms
from .models import UserInfo
class NameForm(forms.Form):
your_id = forms.CharField(label='Your id', max_length=100)
def clean(self):
cleaned_data = super(NameForm, self).clean()
your_id = cleaned_data.get("your_id")
p = UserInfo.objects.all()
if your_id:
for i in p:
if i.usrId not in your_id:
raise forms.ValidationError(
"User not exist."
)
When I do this nothing happens and I get User not exist. for any value.
models.py
class UserInfo(models.Model):
name = models.CharField(max_length=200)
usrId = models.CharField(max_length=200)
age = models.CharField(max_length=200)
poste = models.CharField(max_length=200)
date1 = models.DateTimeField('date of recruitment')
def __str__(self): # __unicode__ on Python 2
return self.name
views.py
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return generate_pdf(request, Type_id)
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'rh/detail.html', {'form': form, 'type_id': Type_id})
Assuming that the user id that you are trying to match does indeed exists (log that id and query the database manually to make sure). Your code should be changed as follows:
try:
p = UserInfo.objects.get(id=your_id)
except UserInfo.DoesNotExist:
raise forms.ValidationError("User not exist.")
This code is shorter and more efficient (you are not fetching all the user objects as in the current version)