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.
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 am making a quiz application, for result calculation I have written logic ..If the value of answer stored in question model is equal to the answer chosen by user then , when user submits each question , score is incrementing by one, but I've failed to build this logic as am a new user to django please help.
Models.py : question along with its 4 options and the correct answer is in question model(These fields are entered by the user who creates a quiz by filling a form). Answer submitted by user is in answer model(This field is entered by user who takes quiz). score is stored in result model.
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
class quiztitle(models.Model):
Quiz_id = models.AutoField(primary_key=True)
Quiz_title = models.CharField(max_length=600)
User = settings.AUTH_USER_MODEL
User_id= models.ForeignKey(User, on_delete=models.CASCADE)
no_of_ques = models.IntegerField(default=10)
class question(models.Model):
Qid = models.AutoField(primary_key=True)
User = settings.AUTH_USER_MODEL
User_id = models.ForeignKey(User,on_delete=models.CASCADE)
Quiz_id = models.ForeignKey(quiztitle,on_delete=models.CASCADE)
Qques = models.TextField()
Qoption1 = models.TextField()
Qoption2 = models.TextField()
Qoption3 = models.TextField()
Qoption4 = models.TextField()
QAnswer = models.TextField()
class answer(models.Model):
Ansid = models.AutoField(primary_key=True)
Qid = models.ForeignKey(question,on_delete=models.CASCADE)
Quiz_id = models.ForeignKey(quiztitle, on_delete=models.CASCADE)
User = settings.AUTH_USER_MODEL
User_id = models.ForeignKey(User, on_delete=models.CASCADE)
Answer = models.TextField()
class result(models.Model):
result = models.AutoField(primary_key=True)
Quiz_id = models.ForeignKey(quiztitle, on_delete=models.CASCADE)
User_id = models.ForeignKey(User, on_delete=models.CASCADE)
score = models.FloatField()
def __str__(self):
return str(self.pk)
here's views.py file
from django.shortcuts import render,redirect,HttpResponseRedirect
from .models import question ,quiztitle ,answer ,result
from django.contrib.auth.models import User
from .forms import CreateUserForm
from django.contrib import messages
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.decorators import login_required
from .decorators import unauthenticated_user,allowed_users
from django.contrib.auth.models import Group
def home_page(request):
return render(request,'Home.html')
def forbidden(request):
return render(request,'error403.html')
#unauthenticated_user
def registerPage(request):
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
user = form.save()
username = form.cleaned_data.get('username')
group = Group.objects.get(name='Student')
user.groups.add(group)
messages.success(request, 'account has been created successfully for username' + username)
return redirect('login')
context = {'form':form}
return render(request,'register.html',context)
#unauthenticated_user
def handle_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request,user)
if request.user.groups.filter(name="Teacher"):
return redirect('quizmaker')
else:
return redirect('student')
else:
messages.info(request, 'Incorrect Username or Password')
context = {}
return render(request, 'login.html', context)
def logoutUser(request):
logout(request)
return redirect('home')#redirect to login page
#login_required(login_url='home')
#allowed_users(allowed_roles=['Teacher','Head'])
def handle_quiz(request):
if request.method=="POST":
# get post parameters
Quiz_title = request.POST.get('Quiz_title')
Quiz_id = request.POST.get('Quiz_id')
no_of_ques = request.POST.get('no_of_ques')
Qid = request.POST.get('Qid')
Qques = request.POST.get('Qques')
Qoption1 = request.POST.get('Qoption1')
Qoption2 = request.POST.get('Qoption2')
Qoption3 = request.POST.get('Qoption3')
Qoption4 = request.POST.get('Qoption4')
QAnswer = request.POST.get('QAnswer')
title = quiztitle(Quiz_title=Quiz_title,Quiz_id=Quiz_id,no_of_ques=no_of_ques)
title.User_id=request.user
title.save()
detail = question(Qid=Qid,Qques=Qques,Qoption1=Qoption1,Qoption2=Qoption2,Qoption3=Qoption3,Qoption4=Qoption4,QAnswer=QAnswer)
detail.User_id=request.user
detail.Quiz_id = title
detail.save()
messages.success(request,'Your question has been added succesfully')
return HttpResponseRedirect('/quizmaker')
return render(request,"createquiz.html")
#login_required(login_url='login')
#allowed_users(allowed_roles=['Student'])
def handle_response(request):
if request.user.is_authenticated:
myuser = User.objects.all()
title = quiztitle.objects.all()
data = question.objects.all()
if request.method == 'POST':
Answer=request.POST.get('Answer')
response = answer(Answer=Answer)
response.User_id = request.user
response.Quiz_id = request.quiztitle
response.Qid = request.question
Answer.save()
return HttpResponseRedirect('/student')
return render(request,"student.html",context={"messages": data ,"topic": title ,"user1": myuser})
def handle_result(request):
if request.user.is_authenticated:
quiz = quiztitle.objects.all()
ques = question.objects.all()
ans = answer.objects.all()
score = 0
if request.method == 'POST':
while(score<=quiz.no_of_ques):
if (ques.objects.QAnswer == ans.objects.Answer):
score += 1
print(score)
sc = request.POST('score')
res = result(sc=score)
res.User_id = request.user
res.Quiz_id = request.quiztitle
result.save()
return HttpResponseRedirect('/sample')
return render(request, "sample.html", context = {"ques":ques , "ans":ans})
In your handle_result function, you have:
quiz = quiztitle.objects.all()
# ...
while(score<=quiz.no_of_ques):
The issue here is that:
The quiz variable is not ONE quiz, it's ALL of them. So it's not an instance, it's a list of instances (technically, a QuerySet of instances)
Therefore, you cannot call quiz.no_of_ques, because quiz is not an instance
That's why you're getting the 'QuerySet' object has no attribute 'no_of_ques' error. Either query one specific instance, or query them all and loop over them.
In views.py handle_result function,
replacing
quiz = quiztitle.objects.all()
with
quizno = quiztitle.objects.values_list('no_of_ques', flat=True)
#....
while(score<=quizno):
it resolves the error 'QuerySet' object has no attribute 'no_of_ques' as it queries one instance i.e no_of_ques
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)
I have a form in my application which has a hidden form field, the value of which I want to set in my corresponding view after submitting the form.
forms.py
class EvangelizedForm(forms.ModelForm):
first_name = forms.CharField(help_text="First Name")
last_name = forms.CharField(help_text="Last Name")
email = forms.CharField(help_text="Email ID")
mobile_no = forms.CharField(help_text="Mobile number")
twitter_url = forms.CharField(help_text="Twitter URL")
twitter_followers = forms.CharField(widget = forms.HiddenInput()) #Hidden form field
class Meta:
model = Evangelized
fields = ('first_name','last_name', 'twitter_url', 'email', 'mobile_no')
models.py
class Evangelized(models.Model):
first_name = models.CharField(max_length=128)
last_name = models.CharField(max_length=128)
email = models.EmailField()
mobile_no = models.CharField(unique=True, max_length = 10, validators=[RegexValidator(regex='^\w{10}$', message='Mobile number should be strictly of 10 digits.')])
twitter_url = models.CharField(unique=True, max_length=128)
twitter_followers = models.CharField(max_length = 128)
views.py
def fillform(request):
follower_count = '250'
if request.method == 'POST':
form = EvangelizedForm(request.POST)
if form.is_valid():
form.fields['twitter_followers'] = follower_count
form.save(commit=True)
return index(request)
else:
form.errors
else:
#form = EvangelizedForm()
if request.user.is_authenticated():
form = EvangelizedForm(initial={'first_name': request.user.first_name,
'twitter_url': 'https://twitter.com/' + request.user.username,
'last_name': request.user.last_name})
else:
form = EvangelizedForm()
context = RequestContext(request,
{'request': request,
'user': request.user, 'form':form})
#return render(request, 'rango/fillform.html', {'form': form, 'context_instance':context})
return render_to_response('rango/fillform.html',
context_instance=context)
Basically, I'm trying to set the value of twitter_followers (which is a hidden form field in forms.py) in my index view, by:
follower_count = '250'
..
..
form.fields['twitter_followers'] = follower_count
By doing this, I'm expecting the value of 'twitter_followers' in the database after submitting the form to be '250'. However, this approach doesn't seem to be working.
What's the right way to set values to certain attributes in the database manually using views?
You need to set it on the model instance, which is the result of form.save. That's the main reason for the commit argument in the first place.
if form.is_valid()
obj = form.save(commit=True)
obj.twitter_follower = follower_count
obj.save()
You can override the save method of the form, with something like this:
def save(self, *args, **kwargs)
twitter_followers = kwargs.pop('twitter_followers', 0)
self.instance.twitter_followers = twitter_followers
super(Evangelized, self).save(args, kwargs)
And then in the view just have to call in this way:
form.save(twitter_followers=250)
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')