django and angular url patterns - django

Sometimes in my code I pass get parameters with URL's. One particular scenario is if the user is not logged in, but puts a URL for a page that requires login, they will be required to login first.
In that case I may have a URL such as: www.example.com/home/#/main/.
The end of the URL /#/main/ is for angular. However, in django when I do the below to get the next parameter above, I do this:
self.request.GET.get('next', self.redirect_url)
The problem is that in this case, next provides everything but the angular portion, so I get: www.example.com/home/.
Is there anyway to get the remaining portion of the URL as well?

You have to urlencode the url before you add it as a parameter. Then it will turn into %23 and insn't the separator for the anchor anymore, which is handled client side only as KVISH described.

Apparantly you can't. Django doesn't even see the anchor, its all handled on client (browser).
How to identify an anchor in a url in Django?
The way I got around this is I use jQuery to set a hidden input field to the hash location, which can be obtained like so:
window.location.hash
The hash gets submitted with the form and I can take it from there.

Related

Postman path parameter following = in the request url

One of the requests for the tool I've been asked to update is the delete request which is structured as follows:
http://{{host_ip}}:{{port}}/lists/list_id=76218cb5fc45605cd632c26f5c5568ac/del
where the list ID will be different every time you send a request.
In order to simplify usage for end users, I want to be able to have them enter everything they need as parameters or headers in the postman GUI as they do for the other requests, rather than modifying the request URL, so I tried something like this:
http://{{host_ip}}:{{port}}/lists/list_id=:list_id/del
but if the : is preceded by an equals sign, the postman parameters tab no longer shows list_id as a path parameter.
Is there a way to make this work using a path parameter? Or is the best solution to explain to users that for the delete request, they need to paste the list_id obtained from the other requests into the request URL?
http://{{host_ip}}:{{port}}/lists/list_id={{list_id}}/del?list_id=1
Now users can pass the list id as query parameter.
In pre-request:
pm.environment.set("list_id",pm.request.url.getQueryString("list_id").split("=")[1])
pm.request.removeQueryParams("list_id")
this will update the list_id varaible and remove the query parameter and send the request in the format you want
If you want to achieve what you are saying then there is no solution for your problem.
But I would suggest you change your URL. As Divyang said, your URL should be like http://{{host_ip}}:{{port}}/lists/{{list_id}}/del or http://{{host_ip}}:{{port}}/lists/del?list_id=123 and then you can use params tab assign values to list_id.
But my best suggestion would be to use RESTful design: http://{{host_ip}}:{{port}}/lists/123123 and make a DELETE request to that URL.

Django weird url call error

I have my Django app. I have a redirect URL(say a 404 page) to be redirected when no other URL matches. Now if any url is called as
mysite.com/something
I am redirected to the 404 page. But
mysite/something/
works fine.
The redirection url added to the end of all:
url(r'^.*/',theview),
When I remove the redirect url from the urls.py, the problem is cleared and the above URL works (without / at the end). Why is the error?
First of all, it would be a good idea to link to your previous post and mention you are using a hack that I gave you, because (A) it's not normal setup and (B) Someone might come up with a better idea than mine
Secondly, you're seeing this behaviour because of normal url processing. See, the urls mysite.com/something and mysite.com/something/ are not the same. To match it with django's urls, the difference would be:
url(r'^something/$')
url(r'^something$')
Since the difference is so minor, when using a normal setup, after failing to find the a url without a forward slash django's common middlewere* will automatically try to add one and test it. It's only then that it would give up and forward you to a 404 page.
However, in your setup, the catch-all url prevents the second round because it does apply to the url without the forward slash. My solution? Don't worry about it. The only reason you're using this hack is because Debug=True means a debug page instead of your custom 404 page, a problem you won't be facing when moving to a production environment
*and a big thanks to #Alasdair who pointed this out in the comments

Django redirect to site root with variable....?

I'm trying to redirect the browser back to the site root and also pass a variable in order to trigger a JS notification function... This is all with Django.
What I have now is this:
urls.py:
url(r'^accounts/password/reset/complete/$', views.passwordResetComplete,
name='password_reset_complete'),
views.py:
def passwordResetComplete(theRequest):
return redirect(home(theRequest, 'Password reset successful'))
def home(theRequest, myMessage=None):
.........
return render_to_response('new/index.html',
{
"myTopbar": myTopbar,
"isLoggedIn": isLoggedIn,
"myMessage": myMessage
},
context_instance=RequestContext(theRequest)
)
I get this error:
NoReverseMatch: Error importing 'Content-Type: text/html; charset=utf-8.......(gives full HTML of page)
I've been working around a few different solutions and nothing seems to work in the way that I need. The closest I've got is to redirect to '/?query-string' with a JS function in root to check for that query-string and run the function if it's present. However, that leaves the query-string in the URL for the duration of the user's navigation of the site (which is 100% AJAX). I want to avoid having any strings/long hrefs in the URL.
Would be really grateful if anyone can tell me how to solve this problem.
HTTP is a stateless protocol, which means that each and every request is entirely unique and separated from anything and everything that has ever been done before. Put more simply, the only way (in HTTP) to "pass a variable" with a URL is to add it to the URL itself (/someobject/1/, for example, where 1 is an object id) or in the querystring (?someobject=1). Either way, the information is embedded in the URL and it's up to your application to decipher that information out of the URL and do something with it.
The concept of a "session" was introduced as a way to provide state to the stateless protocol that is HTTP. The way it works is that the server sends the client a cookie containing some identifiable information (usually, just a session id). Then, the client sends the cookie back to the server in the request headers with every request. The server sees the cookie, looks up the session and continues on seamlessly with whatever is in progress. This is not true state, but it does provide the ability to essentially mimic state, and it's the only way to pass data between requests without actually embedding the data in the URL.
If all you need to return back is a message to the user such as "Password reset successful", you can and should simply use Django's messages framework, which itself uses the session pass the message. It sets a cookie for the client, so that you can redirect to any URL. The cookie will be passed back with the request for that new URL, and Django will add the message from the session into the appropriate place in your template for that URL.
If you need to actually invoke a bit of JavaScript, then you should make the request via AJAX. In the response, you can return any data you want in via JSON (and act on that data however you like) or even return Javascript to be run.
Following the redirect docs, you cannot simply redirect to a view, but only to a url or an object/view that is a assigned to a url already. Thus, you have 2 options:
a) Call the view directly like that:
return home(theRequest, 'Password reset successful')
b) Add a Url patterns like that:
url(r'^your_patterns/$', views.home, msg='',name='home'),
Then you will be able to do what you initally did:
return redirect(views.home,('Password reset successful',))
or from my point of view, even tidier:
return redirect('home',('Password reset successful',))

Correct escaping of % in the URL with Apache

I have a Django project where I have a search page which takes input through a POST and redirect to /search/<search string>/ and this page renders the result. The percentage sign (%) is used as a wildcard in the search (tes%er returns testuser, tester, etc and the url looks like this then: example.com/search/tes%25er/) and everything works fine with the Django development server. If I manually write tes%er in the url it changes to tes%25er automatically.
Now I'm deploying on an Apache server with mod_wsgi and when my search page redirects to example.com/search/tes%er/ I get the server error: Bad Request. Your browser sent a request that this server could not understand.. If I manually add '25' to the url, like the encoded % sign so it looks like the development server it works fine.
Is there a way for Apache to automatically escape the %-sign and create a url that works, understand % unescaped or do I need to do ugly hacks in my search page that builds the url? (I'd rather not do ugly hacks like this cause then the users can't manually add % to the url and get it to work).
Edit: The code that sends the query from the search page to the search url.
if form.is_valid():
if 'search_user' in request.POST:
q = request.POST['search_user']
return redirect('/search/'+q)
As Ignacio already suggested, you should not redirect to an invalid url. So to answer your question:
you can (or perhaps its better to say 'should') not ask your Apache server to escape your url. The reason you escape your URL is because some characters have another meaning. For example, take a querystring:
somedomain.com/?key=value
If we would want to use a ? or a = in your value you would have a problem because your server would think that you are using operators of your querystring.
The same for the %-symbol. When your apache server sees a %-symbol he thinks he will find an enconded and will try to decode it. If your querystring is %20, apache will translate this to a space, while you meant "wildcard20".
In summary: apache decodes your string, so you dont want him to encode it.
But this does not solve your problem. You can solve your problem by changing your code into the following:
from urllib import urlencode
if form.is_valid():
if 'search_user' in request.POST:
q = request.POST['search_user']
return redirect('/search/?q='+urlencode(q))
In case you wonder: what if my user would type /search/?q=%; in that case he'ld have a problem for he has typed an invalid address.
Hope this helps :-).
Wout

quick question: how to set *.domainname.com url in django

I know there are lots of example for how to set http://domainname.com/username
url. But how to set http://username.domainname.com url in django?
Thinking a way to have a unique url for each user as http://username.domain.com like http://garry.posterous.com/
Thanks
As the first step, you need to arrange your DNS server to serve the wildcard domain; this is completely outside Django.
When you managed to do that (i.e. dig garry.posterous.com succeeds), then simply check for the HTTP_HOST request variable in the django view routines.
see Using Subdomains with Django: http://www.rossp.org/blog/2007/apr/28/using-subdomains-django/