So I have an index page that checks if a user is authenticated and redirects them to a workouts.html page if they are authenticated:
def index(request, auth_form=None, user_form=None):
if request.user.is_authenticated():
user = request.user
context = {'user': user}
template = 'workouts.html'
return render(request, template, context)
else:
auth_form = auth_form or AuthenticateForm()
user_form = user_form or UserCreateForm()
template = 'index.html'
context = {'auth_form': auth_form, 'user_form': user_form}
return render(request, template, context)
There are also login/authentication views, but all of that works just fine. Where I'm running into problems is that I wrote a very basic template page for workouts.html to test the authenticated user redirect:
<!DOCTYPE html>
<html>
<head></head>
<body>
<div>These are your workouts, {{ user.username }}.</div>
</body>
</html>
I logged in with a test account. Everything works fine. However, now when I try to add extra html, like a logout form:
<form action="/logout">
<input type="submit" value="Log Out" />
</form>
NOTHING shows up other than the HTML I've already rendered. I've tried restarting the server to the same effect. I also tried adding something much simpler, like
<div>wtf</div>
Nothing shows except the initial message. And if I delete everything on the page, I still get the "These are your workouts, test1" message. Even if I log a user out by hand, I get the same initial message. Why is the template engine not registering my new changes when all other behavior (form authentication, the initial rendering, url routing, etc.) seems to be working fine?
Taking a wild guess, you should close this:
<input type="submit" value="Log Out"
It would look like this:
<input type="submit" value="Log Out" />
Possible reason: until the input is close, the browser interprets everything as part of "inside the input tag" which it never renders because it never closed.
Anyway: ensure your HTML is valid.
Related
This html template from my online class executes as intended, but why? It seems like it is executing out of order:
It calls my python form class using Django's syntax {{form}} to inject the blank fields for the user to fill out (name, email, textbox)
The user can enter and hit the "Submit" button
but then (confusingly) is that it seems the {{form}} class is called again with the entry information as it then successfully prints out user input to the terminal. Why is this?
html in templates.py
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<h1>fill out the form</h1>
<div class="container">
<form method="POST">
{{form}}
{% csrf_token %}
<input type="submit" class="btn btn-primary" value="submitme">
</form>
</div>
</body>
</html>
Form class in views.py
def form_name_view(request):
form = forms.FormName()
if request.method == "POST":
form = forms.FormName(request.POST)
if form.is_valid():
print("VALIDATION SUCCESS")
print("NAME: " + form.cleaned_data['name'])
print("EMAIL: " + form.cleaned_data['email'])
print("TEXT: " + form.cleaned_data['text'])
return render(request, 'first_app/form_page.html', {'form' : form})
Supplemental: the url that uses the html template and my forms class
from django.urls import path
from first_app import views
urlpatterns = [path('formpg', views.form_name_view, name = 'formpg')]
As mentioned in the Django form docs,
Form data sent back to a Django website is processed by a view, generally the same view which published the form. This allows us to reuse some of the same logic.
So your code is executing in the correct order:
When the page is first loaded, a GET request is made and form_name_view() is called. This creates an empty Form object and renders it into a html form with render(request, 'first_app/form_page.html', {'form' : form})
When the html form is submitted, a POST request is made and a new Form object is made with the data sent from the web browser. As in the example, you may want to direct users to another page if their submitted form is valid.
I need some help with django
I have kind of landing page with form, which need to have 3 different states.
Flow looks like this: enter email -> check database for user with that email -> render login or register form, still in same template.
Code looks like this:
.html
// lots of code
<form method="POST" id="form">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" value="send">
</form>
// lots of code
and in views.py i have render method with context
return render(
request,
'apply.html',
context,
)
where in context i placed simple standard django form like:
class ApplyForm(forms.Form):
email = forms.CharField()
phone = forms.CharField()
Is there and way to change ApplyForm to LoginForm or RegisterForm after sending POST from first one, without refreshing whole page?
I though about injecting all three forms to context, sending some ajax request, and then differentiate which form should be displayed, but I'm not sure how could it be done...
thanks in advance!
I am sure this is a silly question but I am trying to understand how forms work in django and I am confused about the action attribute in the template and the httpresponseredirect in views.py
I have the following template:
<form action="/play_outcomes/output/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
And the following view:
def getinput(request):
if request.method == 'POST':
form = get_data(request.POST)
if form.is_valid():
down = form.cleaned_data['get_down']
ytg = form.cleaned_data['get_ytg']
yfog = form.cleaned_data['get_yfog']
return HttpResponseRedirect('/thanks/')
else:
form = get_data()
return render(request, 'play_outcomes/getinput.html', {'form': form})
And finally in forms.py
class get_data(forms.Form):
get_down = forms.IntegerField(label = "Enter a down")
get_ytg = forms.IntegerField(label = "Enter yards to go")
get_yfog = forms.IntegerField(label = "Enter yards from own goal")
When I go to play_outcomes/getinput my form comes up. When I press 'submit' it directs shows the play_outcomes/output page, presumably because that is what is specified by the <form action variable.
Anyway, my question is what is the purpose of the return HttpResponseRedirect('/thanks/') after it has checked form.is_valid(). This is TRUE so it must execute this code. But this return seems redundant.
Please can someone enlighten me on what the return in the views.py is doing
Try replacing the form action with action="". Everything should continue working normally, since your view handles both GET requests (to show an empty form) and POST requests (to process when a form is submitted). When you press "Submit", your browser is sending the form data back to the exact same place it got the original web page from. Same URL, same view (getinput()), same template file (play_outcomes/getinput.html).
Normally, right before that HttpResponseRedirect() part, you'd include some logic to save the content of that form, email a user, do some calculation, etc. At that point, since the user is all done with that page, you typically redirect them to somewhere else on your site.
Edit: empty action
So i'm not even sure how to search for someone who had the same thing happen to them.
I'm working on a django website and my form won't post to my database, instead, i get redirected to a URL containing the information that was in the forms, like this:
<form id="form">
<input type="hidden" id="compinp" name="compinp">
<input maxlength="20" onkeyup="showpost()" name="title" id="titleinput">
{{ captcha }}
</form>
Where compinp is some other data that gets posted, {{ captcha }} is a reCaptcha checkbox that works just fine, and when everything is filled in and getting posted, instead of running the post function from views.py, instead i get redirected to this:
http://localhost:8000/newentry/?compinp=XXXX&title=XXXX&g-recaptcha-response="xxxx-xxxx-xxxx"
It gets posted via jQuery through a button outside of the form, though i tried to add a submit button inside it and got the exact same thing.
The views.py function that handles that looks like this:
def newentry(request):
if request.method == "GET" and request.user.is_authenticated():
#creating objects for the view, works fine too
return render(request, "newentry.html",
{"champlist": complist, "captcha": captcha})
elif request.method == "POST" and request.user.is_authenticated():
captcha = Captcha(request.POST)
title = request.POST.get("title", False)
compname = request.POST.get("compinp", False)
comp = Comp.objects.get(title=compname)
if captcha.is_valid() and title and compname:
newe= entry_generator(request.user, title, comp)
newe.save()
return redirect('/')
else:
return redirect('/')
else:
handle_home(request.method, request.user)
This view tries to post models from another app in the same project, if that makes it any different.
I had added a print attempt at the right after the request check for post it didn't print anything.
Not sure what other info i can give to help, if you want any, just ask (:
You need to add the form method post:
<form id="form" method="post">
<input type="hidden" id="compinp" name="compinp">
<input maxlength="20" onkeyup="showpost()" name="title" id="titleinput">
{{ captcha }}
</form>
I am trying to create a simple subscription form in the front page of my site. I created the view with a model form (the model contains only name and e-mail as attributes). When I go to the root address (GET) it works fine and loads the form. I then fill it with some data, click the submit button (the form action can either be set to '' or '/', the result is the same) and it redirects to the same root page, but it does not load anything, the page remains blank. In the console I can see it calling through POST method, but not even the first print of the view function gets printed.
Any ideas? I know it must be something silly, but I spent sometime in it and haven't yet found out what it could be.
In urls.py:
url(r'', FrontPage.as_view(template_name='rootsite/frontpage.html')),
In rootsite/views.py
class FrontPage(TemplateView):
'''
Front (index) page of the app, so that users can subscribe to
have create their own instance of the app
'''
template_name = 'rootsite/frontpage.html'
def get_context_data(self,
*args,
**kwargs):
c = {}
c.update(csrf(self.request))
print self.request.method
if self.request.method is 'POST':
print 'OK - POST IT IS, FINALLY'
form = NewUsersForm(self.request.POST)
print form.__dict__
if form.is_valid():
form.save()
return HttpResponseRedirect('/' + '?thanks=1')
else:
form = NewUsersForm()
return {'form':form}
You can't return a redirect from within get_context_data - it's for context data only, hence the name.
You should really be using a proper form view for this, which includes methods for redirecting after form validation.
Did you include a csrf_token in your template (as per the example here: http://www.djangobook.com/en/2.0/chapter07.html)?
<form action="" method="post">
<table>
{{ form.as_table }}
</table>
{% csrf_token %}
<input type="submit" value="Submit">
</form>
I could be wrong, but I thought Django wouldn't accept a POST request without a csrf token?