Django path not resetting after use of form - django

On a page called games/vote I have a form that uses the path "add_title/" as its action:
<form method="post" action="add_title/" method="post">
I return the following from the associated view:
return render_to_response('games/votes.html', {'vote_list': not_owned_vote_list,},
context_instance = RequestContext(request))
The url then remains at games/vote/add_title upon return from the view.
I tried changing the path and path_info attributes of the request but to no avail:
request.path = "/games/vote/"
request.path_info = "/games/vote/"
I want the path to be /games/vote upon return to the web page.
What am I doing wrong?

You can't change the path like that. The only way to do it is to tell the browser to redirect to a different URL - which, in fact, is exactly the thing you are recommended to do by the docs after a form POST.
if form.is_valid():
... process ...
return HttpResponseRedirect('/games/vote/')
(Also you should look at using named URLs and reverse() rather than hard-coding the URLs.)

Related

Modal forms and Django URLs, how to work?

html
<form action="{% url 'sp_feedback' %}" method="post">
url
url(r'^feedback/$', views.post_feedback, name="sp_feedback"),
views:
return HttpResponseRedirect("")
In using modal forms, how do you, after hitting submit, return to the page?
In my current setup, the browser redirects to nothing. I'm completely confused on what to put in the url regular expressions.
In my current setup, the browser redirects to nothing.
Because you're redirecting to an empty URL:
return HttpResponseRedirect("")
You've to redirect to the url of the page:
return HttpResponseRedirect('/feedback/')
But it is rather better and convenient to use the redirect() shortcut. Because you can pass it the name of the url and Django will automatically make the redirect to the associated url.
Example:
return redirect('sp_feedback')
It is a good practice to avoid using hardcoded urls in your application.
UPDATE
Since you mention that this form is on every page and you'd like to redirect the user back to that page, here's one solution:
Use request.META['HTTP_REFERER'] in your form view to get the referring page, then use that value to make the redirect:
redirect_to = request.META.get('HTTP_REFERER', '/') # if HTTP-Referer header is not present, just redirect to homepage
return HttpResponseRedirect(redirect_to)

Django: How to include several views/classes in the same url?

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.

Add query string to url in Django

I have a form which sends a POST request and returns a page. The url of this page is defined like this
(r'^result/', 'main.views.eval_form'),
and in the browser the url looks like
mysite.com/main/result
But I also have the url working with a Get Request so the user could save the url and not have to use the form, ie:
mysite.com/main/result?name=Tom&color=blue&etc=etc
Now is there a way to alter the url in the browser after the user uses the form, to include the query string by default? So that the user can copy the url and always return to result?
Thank you!
Change the method attribute of the <form> tag:
<form action="/main/result/" method="GET">
...
</form>
You could do a HttpResponseRedirect to the url with the prefilled querystring from the Post view.
Make sure you don't submit it twice or create an infinite loop.
return HttpResponseRedirect("/result?name={}&color={}&etc={}".format(name, color, etc))
Another way would be to fill your querystring with jQuery or Javascript from the template.
Myself I would take catavaran's approach
If you want to achieve this, you should alter your view to deal with both post and get request.
code may be like this:
def result(request):
name = request.REQUEST.get("name")
but request.REQUEST is deprecated since django 1.7
def result(request):
if request.method == "GET":
name = request.GET.get("name")
if request.method == "POST":
name = request.POST.get("name")

django-allauth redirects again to signup/login forms

I am using django-allauth for local account management. I have customized templates ,login.html and signup.html. Both of these templates are placed in templates/account/ dir and both are accessible properly.
site root i.e localhost:8000 points to index.html which includes using {% include%} both the templates on main page.
form action for signup form in signup.hmtl is set to action="{% url 'account_signup' %}" and that of login.html is set to "{% url 'account_login' %}"
Both the templates appears OK on the main page. The problem arises when I try to use these forms for sigin/login. Instead processing the POST for signup or login I am redirected to locahost:8000/accounts/signup/ for signup and localhost:8000/accounts/login/ for login. I guess I am using the right urls that is account_signup and account_login
I have all settings for allauth. Is this is the default behaviour or I'm missing some thing out? Thanking in anticipation
Well I managed to get rid of the problem after spending some hours. Just in case that some one else caughtup in the same situation I would like to share my solution. The problem was forms have been instantiated by View by using prefix SignUpForm(prefix=signupform) and for that reason allauth class AjaxCapableProcessFormViewMixin(object) (which I don't know how it works) was unable to get data from the fields and its if form.is_valid() was always false as the form has error messages dictionary was containing this field is required for all the fields in the form. Jus to test I removed Prefixing from the form instantiation and it worked but make me feel strange as these kind of hidden errors can take upto indefinite time to resolve especially for some niwbie like me
class AjaxCapableProcessFormViewMixin(object):
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
if form.is_valid():
response = self.form_valid(form)
else:
response = self.form_invalid(form)
return _ajax_response(self.request, response, form=form)

Django: Redirect to current article after comment post

I am trying to use comments application in my project.
I tried to use code ({% render_comment_form for event %}), shown in the documentation here:
Django comments
And the question is how to make the form redirect to the same page, after the submission.
Also the big question is:
Currently if we have any error found in the for, then we're redirected to preview template.
Is that possible to avoid this behaviour and display errors over the same form (on the same page)?
I will show you how I resolved it in my blog, so you could do something similar. My comments are for Entry model in entries application.
First add new method for your Entry (like) object.
def get_absolute_url(self):
return "/%i/%i/%i/entry/%i/%s/" % (self.date.year, self.date.month, self.date.day, self.id, self.slug)
It generates url for entry objects. URL example: /2009/12/12/entry/1/lorem-ipsum/
To urls.py add 1 line:
(r'^comments/posted/$', 'smenteks_blog.entries.views.comment_posted'),
So now you should have at least 2 lines for comments in your urls.py file.
(r'^comments/posted/$', 'smenteks_blog.entries.views.comment_posted'),
(r'^comments/', include('django.contrib.comments.urls')),
For entries (like) application in views.py file add function:
from django.contrib.comments import Comment #A
...
def comment_posted(request):
if request.GET['c']:
comment_id = request.GET['c'] #B
comment = Comment.objects.get( pk=comment_id )
entry = Entry.objects.get(id=comment.object_pk) #C
if entry:
return HttpResponseRedirect( entry.get_absolute_url() ) #D
return HttpResponseRedirect( "/" )
A) Import on top of file to have
access for comment object,
B) Get
comment_id form REQUEST,
C) Fetch
entry object,
D) Use
get_absolute_url method to make
proper redirect.
Now:
Post button in comment form on entry site redirects user on the same (entry) site.
Post button on preview site redirects user on the proper (entry) site.
Preview button in comment form on entry site and on preview site redirects user on preview site
Thankyou page is not more in use (That page was quite annoying in my opinion).
Next thing good to do is to override preview.html template:
Go to django framework dir, under linux it could by /usr/share/pyshared/.
Get original preview.html template from DJANGO_DIR/contrib/comments/templates/comments/preview.html
Copy it to templates direcotry in your project PROJECT_DIR/templates/comments/entries_preview.html
From now on, it shoud override default template, You can change extends in this way: {% extends "your_pagelayout.html" %} to have your layout and all css files working.
Take a look at "Django-1.4/django/contrib/comments/templates/comments/" folder and you will see in the "form.html" file, there is the line
{% if next %}<div><input type="hidden" name="next" value="{{ next }}" /></div>{% endif %}
Therefore, in the Article-Detail view, you can include the "next" attribute in the context data, and then the comment framework will do the rest
class ArticleDetailView(DetailView):
model = Article
context_object_name = 'article'
def get_context_data(self, **kwargs):
context = super(ArticleDetailView, self).get_context_data(**kwargs)
context['next'] = reverse('blogs.views.article_detail_view',
kwargs={'pk':self.kwargs['pk'], 'slug': self.kwargs['slug']})
return context
Simplify Django’s Free Comments Redirection
Update: Now have the option to redirect as part of the comment form: see https://django-contrib-comments.readthedocs.io/en/latest/quickstart.html#redirecting-after-the-comment-post
This is a really simple redirect to implement. It redirects you back to the page where the comment was made.
When a comment is posted, the url comments/posted/ calls the view comment_posted which then redirects back to the referer page.
Be sure to replace [app_name] with your application name.
views.py
from urlparse import urlsplit
def comment_posted( request ):
referer = request.META.get('HTTP_REFERER', None)
if referer is None:
pass
try:
redirect_to = urlsplit(referer, 'http', False)[2]
except IndexError:
pass
return HttpResponseRedirect(redirect_to)
urls.py
( r'^comments/posted/$', '[app_name].views.comment_posted' ),