When I submit the form (eg: below), url gets redirected to localhost:8000/test/result/, and I get some result. This step works fine.
However, when I click on browser back button to go back to the initial form, Firefox doesn't load the form, although url has changed to localhost:8000/test/. I get a blank page. Also, if I click the back button again, it takes me to localhost:8000 page. Chrome and IE works though.
What am I doing wrong and how can I fix this FF issue?
Many thanks in advance.
#---test.html---
<form id="input-form" action="{% url test.views.main_view %}" method="post" enctype="multipart/form-data">{% csrf_token %}
...
</form>
#---views.py---
class MainView(FormView):
template_name = 'test.html'
form_class = UserInputForm
success_url = 'result/'
def form_valid(self, form):
...
#---urls.py---
urlpatterns = patterns('test.views',
url(r'^$', view='main_view', name='main-view'),
url(r'^result/$', view='result_view', name='result-view'),
)
I have a feeling this is the issue. Failing that, something that will definitely work is setting your Cache-Control header to “no-cache, must-revalidate, no-store” – but that's a nasty brute force solution.
Related
I'm a beginner in Django. So I do sincerely apologize in advance if my question is dummy. That being said, I've been trying to search for the answer on the Internet for days with no success so far.
In a nutshell, I have a form made of a single MultipleChoiceField.
When the user connects for the 1st time on the webpage with this form, he can check the boxes which are appropiate and then hit a Submit button. So far, I manage to do it.
Where I get stuck is on how to redirect the user to another form (in total there will be 10 forms, until he reaches a "complete" webpage).
Using redirect, I know how to redirect the user to a static webpage, but I could not figure out how to redirect him to a dynamic webpage (ie based on the variables values within my view).
Below are the scripts I wrote to give you a better idea of what I'm trying to achieve:
[views.py]
def my_form(request, id):
form = MyForm(request.POST or None, form_id=id)
if form.is_valid():
# DO SOME CLEAN-UP...
form.id += 1
id += 1
return render(request, 'my_form.html', {'form': form, 'id': id})
[urls.py]
urlpatterns = [
...
] +
[url('my_form', views.my_form, {'id': 1}, name='my_form'))]
As you can imagine, my aim was to start with id 1, and then everytime the user clicks the Submit button, he gets redirected to the id + 1 form until number 10.
With the above code, I always get redirected to page with id = 1.
There must be something I did not understand in request usage, but I cannot figure out what. And the many questions I red on this board and others did not help.
I would be more than happy to ear about where I went wrong from those of you with more Django experience than me.
Thank you very much in advance.
Sophie :)
[EDIT 06/10/2018]
The code looks as per the below now:
[my_form.html]
<form action="{% url 'my_form' %}" method="post">
{% csrf_token %}
<table border="1">
{{ form.as_p }}
</table>
<input type="submit" value="Submit" class="btn btn-primary"/>
</form>
[urls.py]
urlpatterns = [
...
] +
[path('question/<int:id>/', views.my_form, name="my_form")]
Maybe HttpResponseRedirect help you.
return HttpResponseRedirect(reverse('my_form', kwargs={'id':id})
I have seen a number of forums and posts but still couldn't get the handle of it. Here in django doc, it says
The CSRF middleware is activated by default in the MIDDLEWARE setting. If you override that setting, remember that 'django.middleware.csrf.CsrfViewMiddleware' should come before any view > middleware that assume that CSRF attacks have been dealt with.
If you disabled it, which is not recommended, you can use csrf_protect() on particular views you want to protect (see below).
In any template that uses a POST form, use the csrf_token tag inside the > element if the form is for an internal URL, e.g.:
form action
{% csrf_token %}
Based on that, in my html template I did simply:
<form id='frm' name='frm' method="post" action="{% url 'gettip' %}" >
{% csrf_token %}
<input type="text" name="tipid" name="tipid">
<input type="submit" value="Get Tip Value"/>
</form>
I expected the CSRF_token to create the hidden element since the middleware is already loaded. I see no element in the form and I get CSRF error.
The form is not associated with any model. I haven't used forms.py either. My current view is simply to output something:
def gettip(request):
if request.POST:
return HttpResponse('You requested a tip')
#from a weblink, i was told to add the following but it made no difference
context = {}
return render_to_response('tip.html',context, context_instance=RequestContext(request))
The error I am getting is obviously CSRF missing cos the hidden element is not there at all.
I am migrating from PHP and this is giving me a hard time. Though my form is not for login purposes, I couldn't get this one to work either for the same error. I am on django 1.10 and just want to get a positive response when form is submitted.
Don't use render_to_response, it's obsolete. Use render instead.
from django.shortcuts import render
def gettip(request):
if request.POST:
return HttpResponse('You requested a tip')
context = {}
return render(request, 'tip.html', context)
If the template containing the form is rendered by another view, you'll have to fix that view as well.
I would like to have both a contact form, a newsletter form and a photo slider/portofolio in index.html. Everything drawn into this page only.
Am I correct to assume it has something to do With "URL dispatcher" in the documentation? And could someone please help me with some examples on how to point everything to the same URL?
Want everything to redirect back to the index when done, after email has been sent, after registering for newsletter and so on. Just to explain better what I actually mean here as I don't have the knowledge to do it in correct terminology.
Thanks in advance for all the help I can get.
As a possible solution you can create index page with multiple forms. Each form will redirect on post to it own view, for example:
First form:
<form action="{% url 'myapp:index_one' %}" enctype="multipart/form-data" method="post">
Second form:
<form action="{% url 'myapp:index_two' %}" enctype="multipart/form-data" method="post">
In each view you create all the forms and pass them to index.html
def index_one():
indexForm1 = index_form1()
indexForm2 = index_form2()
if request.POST:
indexForm = index_form1(request.POST, request.FILES)
//process first form here
//load index.html and pass context with forms
In second view you do the same but on POST you process another form:
def index_two():
indexForm1 = index_form1()
indexForm2 = index_form2()
if request.POST:
indexForm2 = index_form2(request.POST, request.FILES)
//process second form here
//load index.html and pass context with forms
I have such solution in production and it is working fine.
Please I am a newbie in programming,dont be pissed if my question is too rudimentary or annoying.I have a model that goes like this
class Feed(models.Model):
user=models.ForeignKey(User,on_delete=models.CASCADE,related_name='feeds')
text=models.TextField(blank=False,max_length=500)
user_like=models.ManyToManyField(User,related_name="likes",blank=True)
I want to create a stand-alone Like button for this model to add user to user_like when click by a user in template.I have a view like this
def like_feed(request,pk):
feed=get_object_or_404(Feed,pk=pk)
user=request.user
if request.method=='POST'
if feed.user_like.filter(id=user.id).exists():
feed.user_like.remove(user)
#make the change and reload the page
return render(request , 'index.html' ,{'feed':feed,})
else:
feed.user_like.add(user)
#make the change and reload the page
return render(request , 'index.html' ,{'feed':feed,})
urls.py
url(r'^likes/(?P<pk>\d+)/$',views.like_feed,name='like_feed_url')
and somewhere in the template I have
<form action="{% url 'like_feed' pk=feed.pk %}" method="post">
<input type="button" id="like" name="like_button" value="Like" /></form>
As I said I am not really sure what I am doing,I am just experimenting.Kindly help me out.
All,
I am having a field day with page refetching. Any help or pointer will be greatly appreciated!! The behavior is a bit specific to mobile browser.
Problem:
I have two pages and created a shortcut link to pg#1 on the home screen. Through a form submit button, user is taken from pg#1 to pg#2. All that is working fine.
Now once I am on pg#2. I will leave the browser and click the shortcut later. The browser will stay on pg#2 and won't go to pg#1 even though the path in URLS is different between the two views.
Update#1:
Here is the code snippets.
def sendmsg(request):
if request.method =='POST':
messages.add_message(request, messages.INFO, "Hello world")
return redirect ('rcvmsg')
return render_to_response('sendMsg.html',RequestContext(request))
def rcvmsg(request):
'''view that receives the msg.'''
printMsg ='Didnt get a message'
if messages:
thisMsg = messages.get_messages(request)
for rcvMsg in thisMsg:
printMsg = rcvMsg
return render_to_response('rcvMsg.html',{'print_msg':printMsg},RequestContext(request))
URL:
url(r'^rcvMsg/','mydomain.mainApp.views.rcvmsg',name='rcvmsg'),
(r'^sendMsg/code','mydomain.mainApp.views.sendmsg'),
It is almost like Django decides that since I have already visited view#1, it doesn't need to fetch it again. This problem or behavior doesn't happen if I move the same code that handle the two views and the templates to a bare bone test project.
Setup:
I am using django-registration, context session. I am not using any HTML caching tag.
I already have DEBUG turned on in my settings.py. Are there other ways that I can tell what the server is doing.
Thanks in advance.
pdxMobile
Found out what the problem was. I have the form action set back to the view itself in my template. I guess the browser thinks that since the action is back to the same page and so a reload is unnecessary.
Before:
<form action="." method="post">
{% csrf_token %}
Fix:
<form action="./next" method="post"> <--the "next" is fictitious & doesn't exist in URL-->
{% csrf_token %}
Hope this useful for someone someday.
Cheers. -P