I am creating a search bar that takes a username and locates that Player in the database. I create a PlayerStatsForm() that takes in the request, searches the database for players with the username from the request, and returns that players stats. I know that the username is being passed by the html form to my python code correctly and the form is passing true for PlayerStatsForm.is_valid() but when I try and call playerstatsform.username it says that the attribute is not found. If I add model = Player and change forms.Form to ModelForm in PlayerStatsForm it tries to insert a player with no username or id into the database and says that the column user_id cannot be null
<tr><th><label for="id_username">Username:</label></th><td><input type="text" name="username" value="testuser" required id="id_username"></td></tr>
Internal Server Error: /elousers/elosearch/
This is the error from the terminal so is the issue that id=id_username and not name=id_username?
playerstatsform:
class PlayerStatsForm(forms.Form):
username = forms.CharField()
class Meta:
fields = (
'username',
)
views.py:
def elosearch(request):
if request.method == 'POST':
print("Post was found")
if 'get_player' in request.POST:
playerstatsform = PlayerStatsForm(request.POST)
print("post found")
if playerstatsform.is_valid():
player = Player.objects.get(name=playerstatsform.cleaned_data['username'])
print("player found successfully")
player_elo = player.elo
player_name = player.name
print(player_elo)
context1 = {'playername': player_name, 'playerelo': player_elo}
return render('elousers/elosearch.html', context1)
else:
invalid_player_entry = "Username not added. Please register below."
context1 = {'invalid_player': invalid_player_entry}
return render(request, 'elousers/elosearch.html', context1)
elif 'addgame' in request.POST:
gameform = GameForm(data=request.POST)
if gameform.is_valid():
gameform.save()
game_success = "Game Successfully Added!"
context2 = {'game_display': game_success}
return render(request, 'elousers/elosearch.html', context2)
else:
game_invalid = "Invalid entry. Please try again."
context2 = {'game_display': game_invalid}
return render(request, 'elousers/elosearch.html', context2)
else:
return render(request, 'elousers/elosearch.html')
elif request.method == 'GET':
print("get was called")
return render(request, 'elousers/elosearch.html')
expect the database to query using the username provided by the form but I am getting 'PlayerStatsForm' object has no attribute 'username'
You can obtain the value from the playerstatsform through the .cleaned_data attribute [Django-doc], which is a dictionary. By using playerstatsform.username, you get access to the form field, but this will render the HTML representation of the field if you pass it through str.
def elosearch(request):
if request.method == 'POST':
print("Post was found")
if 'get_player' in request.POST:
playerstatsform = PlayerStatsForm(request.POST)
if playerstatsform.is_valid():
player = Player.objects.get(name=playerstatsform.cleaned_data['username'])
player_elo = player.elo
player_name = player.name
context1 = {'playername': player_name, 'playerelo': player_elo}
return render(request, 'elousers/elosearch.html', context1)
Note that it is possible that no Player object exists for the given name, or perhaps, if that field is not unique=True, multiple Players can have that name, so you probably should at least try-catch these cases, and handle these accordingly.
You thus probably will need to do something like:
def elosearch(request):
if request.method == 'POST':
print("Post was found")
if 'get_player' in request.POST:
playerstatsform = PlayerStatsForm(request.POST)
if playerstatsform.is_valid():
try:
player = Player.objects.get(
name=playerstatsform.cleaned_data['username']
)
except (Player.DoesNotExist, Player.MultipleObjectsReturned):
player = None
player_elo = None
player_name = None
else:
player_elo = player.elo
player_name = player.name
context1 = {'playername': player_name, 'playerelo': player_elo}
return render(request, 'elousers/elosearch.html', context1)
Related
This is my signup view:
def signup(request):
next = request.GET.get('next', '')
print(next)
if request.user.is_authenticated:
return redirect('/')
else:
if request.method == "POST":
first_name=request.POST['first_name']
email=request.POST['email']
password=request.POST['password']
cpassword=request.POST['cpassword']
signup_uri = f'/signup?next={next}'
if password==cpassword:
if User.objects.filter(email=email).exists():
messages.info(request,'Email already in use')
return redirect(signup_uri)
elif User.objects.filter(mobile=mobile).exists():
messages.info(request,'Mobile Number already in use')
return redirect(signup_uri)
else:
user=User.objects.create_user(first_name=first_name,email=email,password=password)
user.save();
return redirect(f'/login?next={next}')
else:
messages.info(request,'Passwords not matching')
return redirect('signup_uri')
else:
return render(request,'signup.html')
The problem I am facing is that when I am printing next under def signup it is printing it correctly but when it has to redirect it redirects without showing anything as next in url. That is signup_uri = f'/signup?next={next}' and return redirect(f'/login?next={next}') are showing the {next} as empty.What could be the reason?Any help would be appriciated.
Based on the definition of the signup method, you are only retrieving the value of the next parameter only for the GET request. But when you are trying for a POST request, you do not retrieve the value of the next parameter. For this reason, the value of the next variable is set to "" and hence, the value of the signup_uri variable is being set as "/signup?next=" as well as for the login redirecting url ("/login?next=") too. In order to get rid of this problem, your code should be similar to as follows.
def signup(request):
next = request.GET.get('next', '')
print(next)
if request.user.is_authenticated:
return redirect('/')
else:
if request.method == "POST":
first_name = request.POST['first_name']
email = request.POST['email']
password = request.POST['password']
cpassword = request.POST['cpassword']
next = request.POST.get("next", "")
signup_uri = f'/signup?next={next}'
if password == cpassword:
if User.objects.filter(email=email).exists():
messages.info(request,'Email already in use')
return redirect(signup_uri)
elif User.objects.filter(mobile=mobile).exists():
messages.info(request,'Mobile Number already in use')
return redirect(signup_uri)
else:
user = User.objects.create_user(first_name=first_name, email=email, password=password)
user.save();
return redirect(f'/login?next={next}')
else:
messages.info(request, 'Passwords not matching')
return redirect('signup_uri')
else:
return render(request, 'signup.html')
Here I am trying to redirect to another page if the form is submitted successfully but this code is not working properly .The code saves the form data sends the email , everything is fine but the problem is while redirecting to another page if the form succeed. The error I get is:
Django Version: 2.0.6
Exception Type: ValueError
Exception Value:
dictionary update sequence element #0 has length 0; 2 is required
context_processor.py
def volunteer_page2(request):
volunteer = Volunteer.objects.all().order_by('date')
if request.method == 'POST':
form = VForm(request.POST or None)
if form.is_valid():
name = form.cleaned_data['name']
email = form.cleaned_data['email']
message = "{0} with email address {1} has sent you new message \n\n{2}".format(name, email, form.cleaned_data['message'])
form.save(commit = False)
try:
send_mail(name, message, 'appname <settings.EMAIL_HOST_USER>', ['myemail'])
except:
return HttpResponse('Invalid header found')
form.save()
messages.success(request, 'Success')
return redirect('volunteer_page')
else:
messages.error(request, "Sorry try again")
else:
form = VForm()
return {'volunteer': volunteer, 'form':form}
views.py
def about_page(request):
about = About.objects.all().order_by('date')
banner = Banner.objects.all()
testimonial = Testimonial.objects.order_by('-pk')[0:2]
nav = Nav.objects.all()
footer = Footer.objects.all()
latest_event2 = Events.objects.order_by('-pk')[0:2]
context = {
'about': about,
'testimonial': testimonial,
'footer':footer,
'banner': banner,
'nav': nav,
'latest_event2': latest_event2,
}
return render(request, 'myapp/about.html', context)
settings.py
'myapp.context_processor.volunteer_page2'
Django's context processor should always return dictionary. In your code you are returning HttpResponse also. This is problem.
I have a webpage where user chooses one object from a model. Based on the button clicked, certain actions are executed. One of the actions is by calling one of the views, and dislaying another webpage.
So, when user visits http://127.0.0.1:8000/clinic/manage, he sees the below form:
Code:
#login_required
def manage_clinics(request):
msg = ''
if request.method == 'POST':
clid = int(request.POST.get('clinics'))
print("POST details", request.POST)
if request.POST.get('createdoctor')=='Create Doctor':
clinicobj = Clinic.objects.get(clinicid=clid)
print("Creating Doctor for clinic:", clinicobj)
createdoctor(request, clinicobj.label)
else:
form = ChooseClinicMetaForm()
return render(request, 'clinic/manageclinics.html', {'form': form, 'msg': msg})
If he clicks on 'Create Doctor', the following view function is to be executed:
#login_required
def createdoctor(request, cliniclabel):
msg =''
cliniclink = '/clinic/'+cliniclabel+'/createdoctor'
cl = Clinic.objects.get(label=cliniclabel)
if request.method == 'POST':
print("POST details", request.POST)
form = DoctorMetaForm(request.POST)
if form.is_valid():
print("Form is valid.")
# form.save()
username = request.POST.get('username')
name = request.POST.get('name')
email = request.POST.get('email')
phone = request.POST.get('phone')
msg = SaveDoctortoSQLNew(request)
print(msg)
if 'Error:' not in msg:
doctorobj = doctor.objects.get(name=name, email=email, phone=phone, username=username)
clinicobj = Clinic.objects.get(label=cliniclabel)
permobj = ClinicPermissions(clinicid=clinicobj, doctorid=doctorobj, viewperms =1)
permobj.save()
msg = "Successfully created a doctor and assigned permissions"
else:
msg = "Invalid details."
print(msg)
else:
# cl = Clinic.objects.get(label=cliniclabel)
form = DoctorMetaForm()
return render(request, 'clinic/doctorprofile.html', {'form': form, 'rnd_num': randomnumber(), 'cliniclink': cliniclink, 'msg': msg, 'clinic':cl})
When this is executed, I get the following exception:
[14/Oct/2018 14:40:37] "GET /appointments/static/appointments/js/bootstrap.min.js.map HTTP/1.1" 404 1758
POST details <QueryDict: {'csrfmiddlewaretoken': ['3Jt28ToKqHiP6rGaTmbOOZH0yNRaU1TCOx427C6sV42VCbFrbrdJVlpzaSQiI3EK'], 'clinics': ['1'], 'createdoctor': ['Create Doctor']}>
Creating Doctor for clinic: Dr Joel's ENT Clinic
POST details <QueryDict: {'csrfmiddlewaretoken': ['3Jt28ToKqHiP6rGaTmbOOZH0yNRaU1TCOx427C6sV42VCbFrbrdJVlpzaSQiI3EK'], 'clinics': ['1'], 'createdoctor': ['Create Doctor']}>
Invalid details.
2018-10-14 14:40:40,928 django.request ERROR Internal Server Error: /clinic/manage
Traceback (most recent call last):
File "/home/joel/.local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/joel/.local/lib/python3.6/site-packages/django/core/handlers/base.py", line 137, in _get_response
"returned None instead." % (callback.__module__, view_name)
ValueError: The view clinic.views.manage_clinics didn't return an HttpResponse object. It returned None instead.
So this is apparently because no HttpResponse object is returned. But doesnt the createdoctor function return just that? Or is python complaining about the return of the statement createdoctor(request, clinicobj.label)? Am I supposed to wrap this up in a HttpResponse?
It appears like you forgot to add return in manage_clinics
#login_required
def manage_clinics(request):
msg = ''
if request.method == 'POST':
clid = int(request.POST.get('clinics'))
print("POST details", request.POST)
if request.POST.get('createdoctor')=='Create Doctor':
clinicobj = Clinic.objects.get(clinicid=clid)
print("Creating Doctor for clinic:", clinicobj)
return createdoctor(request, clinicobj.label)
else:
form = ChooseClinicMetaForm()
return render(request, 'clinic/manageclinics.html', {'form': form, 'msg': msg})
I have a view with model form, the ModelForm doesn't really contain all fields in the model. other fields I've used the methods of form.field = value before form.save(), but all of this fields being saved as default. none take the value am trying to give. here are the code :
def PostAd(request):
ad_post_form = AdPostForm()
if request.user.is_authenticated:
obj = Account.objects.get(user=request.user)
if request.method == "POST":
ad_post_form = AdPostForm(request.POST, request.FILES)
if ad_post_form.is_valid():
ad_post_form.created_by = request.user
if obj.role == 'admin':
ad_post_form.is_active = True
ad_post_form.save()
return redirect('home')
else:
ad_post_form = AdPostForm(request.POST, request.FILES)
else:
if request.method == "POST":
ad_post_form = AdPostForm(request.POST, request.FILES)
if ad_post_form.is_valid():
otp_number = random.randint(100000, 999999)
ad_post_form.otp = otp_number
ad_post_form.is_activated = False
ad_post_form.save()
current_id = ad_post_form.id
current_contact_email = request.POST.get('contact_email')
email_url_active = str(settings.URL_LOCAL) + 'new_ad/adidnumberis' + str(
current_id) + '/needactivate/activate/' + str(otp_number) + '/'
email_msg = "Please Confirm adding the Ad to Jehlum. Click link " + email_url_active
email = EmailMessage('Active Email', email_msg, to=[current_contact_email])
email.send()
return redirect('home')
else:
ad_post_form = AdPostForm()
context = {
'ad_post_form': ad_post_form,
}
return render(request, 'pages/post-ad.html', context)
the problem is ad_post_form.is_active = True is being saved as False(default)
also ad_post_form.otp = otp_number is being saved as 0 (default) and i need to give the spicific values i assigned here .
You need to get the model instance and set the attributes there. You so this by calling save with commit=False.
if ad_post_form.is_valid():
ad_post = ad_post_form.save(commit=False)
ad_post.created_by = request.user
...
ad_post.save()
I have a view like:
def Registration(request):
RegForm = RegistrationForm(request.POST or None)
if request.method == 'POST':
if RegForm.is_valid():
clearUserName = RegForm.cleaned_data['userNm']
clearPass = RegForm.cleaned_data['userPass']
hashedpasswithsalt = bcrypt.hashpw(clearPass, bcrypt.gensalt(14))
RegForm.save()
try:
return HttpResponseRedirect('/Newuser/?userNm=' + clearUserName)
except:
raise ValidationError(('Invalid request'), code='300') ## [ TODO ]: add a custom error page here.
else:
RegForm = RegistrationForm()
return render(request, 'VA/reuse/register.html', {
'RegForm': RegForm
})
RegistrationForm
class RegistrationForm(ModelForm):
userPass = forms.CharField(widget=forms.PasswordInput, label='Password')
class Meta:
model = Client
fields = ['userNm','userPass']
Why is it storing in plaintext?
I'm trying to take the cleaned_data[] of userPass from a modelfrom and hash it prior to sending to the db.
Try bcrypt.hashpw(clearPass.encode("utf-8"), bcrypt.gensalt(14)).
This is because your clearPass is by default an Unicode object and that it can't be directly used in your hashing function, the encode("utf-8") converts it into a standard string and then it can be hashed.