My website has a list of pages that are under /record and available only with query parameters of type and id. Like so:
/record?type=poem&id=175
I am using the django next redirect to go from the login page to the previous page. I initially used href="{% url 'auth:login' %}?next={{ request.path }}" to redirect, but it didn't take the query parameters (i.e type and id). This takes the user to
/login/?next=/record
I then used href="'{% url 'auth:login' %}?next={{ request.path }}'+window.location.search". However, this doesn't work as well. This takes the user to
/login/?next=/record?type=poem&id=175
but it finally redirects to
/record
How do I redirect using next along with query parameters? Is this behavior not possible?
You need to escape special characters in the URL, namely '?', '&' and '='.
While there is django.utils.encoding.escape_uri_path, it doesn't escape the ampersand (&), which is a problem because it will be interpreted as the end of the next parameter and the beginning of another.
Instead, you can use urllib.parse.quote:
from urllib.parse import quote
current_url_escaped = quote(request.get_full_path())
and in the template:
href="{% url 'auth:login' %}?next={{ current_url_escaped }}
You can use HttpRequest.get_full_path() method along with urlencode template filter to get the current url along with the query string.
HttpRequest.get_full_path()
Returns the path, plus an appended query string, if applicable.
href="{% url 'auth:login' %}?next={{request.get_full_path|urlencode}}
Related
How can I send a URL from a template to a view? I have noticed that a normal string works but a URL doesn't. Here is what I have tried.
path('imageviewer/<str:theimage>', mainviews.imageviewer, name="imageviewer"),
def imageviewer(request, theimage):
response = render(request, "imageviewer.html", {"theimage": theimage})
return response
How I attempt to pass it : (value.image) is a url
<a href="{% url 'imageviewer' theimage=value.image %}" class="effect-lily tm-post-link tm-pt-60">
Error I Get:
Reverse for 'imageviewer' with keyword arguments '{'theimage': 'https://storage.googleapis.com/katakata-cb1db.appspot.com/images/humours/1643758561'}' not found. 1 pattern(s) tried: ['imageviewer/(?P<theimage>[^/]+)\\Z']
Thank you.
You need to escape the image so that it can be used in a URL, use the built-in filter urlencode
{% url 'imageviewer' theimage=value.image|urlencode %}
Your urlpattern also needs to accept slashes and other chars, use the path converter instead of str as it accepts any non-empty string
path('imageviewer/<path:theimage>', mainviews.imageviewer, name="imageviewer"),
I'm having a tough time figuring out how to parse my URL GET data and send it to the right view.
I have a search view that only has a search input:
template/search.html
<form action="http://domain.com/schools/search/" method="GET" >
<input type="text" name = "q_word">
<input type="submit" value="Search"/>
</form>
When a user enters in a search term, I want to send that data to another view to parse and use in a geocoding function I wrote. Here is a look at my urls.py:
url(r'^schools/search/$', school_views.find_school, name="find_school"),
url(r'^schools/search/(?P<address>[\w ]+)$', school_views.geo_locate, name="geo_locate"),
I want to grab the GET data from a URL (after they've entered in the info), and pass it as an address argument to my school_views.geo_locate function.
This set up works great when you manually type out a URL like: schools/search/150%20main%20Street
But when a user submits any form data, the URL passed is /schools/search/?q_word=150+west+main and I'm just kicked back to my search template.
I think my regex needs to be tweaked in my second url argument, but I just keep returning to the search page after submission, with no data going to my geo_locate view. Is this a URLs problem?
GET data is not passed in the URL parameters. Don't try to capture it in the regex. Just get it from request.GET inside the view.
My form submits as follows
<form class="form-signin" role="form" action="{% provider_login_url "facebook" method="js_sdk" next="/next"%}">
I overrode the DefaultAccountAdapter with my own AccountAdapter with method
def get_login_redirect_url(self, request):
print request.GET['next']
...
But request loses the next parameter and the print returns an error because there is no "next" in request.GET.
Why can't I access the next parameter?
I was originally using get_login_redirect_url to handle different url redirects after creation of social versus username/password users. Now, I need to be able to specific the next parameter in the URL for another variant of behavior for social user login but am unable to access the next parameter because it does not seem to be passed.
I am not sure whether I could give the precise solution for your issue. But I think got the point.
To access the next parameter from url,
The url should be,
http://127.0.0.1:8000/index?next=2
If you have to form the url in this above manner,you can get access to the next argument from request object in your corresponding view method
print request.GET.get('next')
So, please make sure to format request url with proper querystring refer
To your case,
I have no idea about {% provider_login_url %} template tag
I am assuming after your tag rendered it yields the url index, then i am appending my querystring next
<form class="form-signin" role="form" action="/index?next=someValue">
you may try additionally,
{% provider_login_url "facebook" next=next %}
source
I came across with a similar problem. However, I wasn't signing in with facebook. request.GET was always empty.
I think you could try using jQuery to manually append next parameter to the action attribute of <form>. See this question. It solves my problem.
This link can not pass parameter to view.py
profile
It gives an error page not found, 127.0.0.1:8000/profile/edit/
There is not parameter there, even {{costumer.slug}} returns a string
Rest of template has no porblem to pass a parameter like this:
{{j.title}}
What can be wrong here?
Your problem is that you are missing a leading slash, so the browser is concatenating the URL with the one you're already on (you're on '/profile', you click 'edit', you go to '/profile/edit').
But you shouldn't be building up URLs like that. You should use the url tag. Assuming your URLconf is this:
url(r'^edit/(?P<slug>\w+)/$', 'profile.views.edit_profile', name='edit_profile')
you would do this in the template:
<a href="{% url 'edit_profile' slug=costumer.slug %}">
My url is :
1. http://localhost:8000/docs/[slug]
2. http://localhost:8000/docs/[slug]/login
1. url calls before number 2. url I want to send
the slug value to the function mapped by the url 2. In template
what should i wrote for form action event.
I agree, this is nearly incomprehensible, but I'm going to give it a go in terms of an answer.
In terms of calling sequence, there is none. A user might first visit url 2 or url 1. You have no way of guaranteeing which they will try to access first because they might directly input the url into their browser. The only thing you can do is set a variable in request.session's dict and test for it with your login url.
In terms of passing slug to another url, if you're having a url with this in it:
urls = ('',
url(r'docs/(?P<slug>\w+)', 'app.views.slug', name='slug-view'),
url(r'docs/(?P<slug>\w+)/login', 'app.views.slug_login', name='slug-login'),
#..
)
Then in your template you can do this:
<form action="{% url slug-login slugname %}" method="POST">
Your views.py would look something like this.
def slug(request, slug):
#
#
return render_to_response('templatename.html', {'slugname':slug}, context_instance=RequestContext(request))
def slug_login(request, slug):
# do something with slug.
This way, when you access the slug view, you pass into the template a variable called slugname, which the template uses with django's url library to resolve a specifically named url in urls.py with one named parameter, slug, which it will assign the value of slugname.
I suggest you try it.
I might also reccoment you read up on the django url dispatcher. Your use of regex without named parameters is acceptable but really not best practice. I'd also suggest django shortcuts (render_to_response) as a quick way to pass variables into templates and the django template language itself.