wsgi.input from request.meta - django

I'm upgrading to Django 1.8, and in one of my views I need to accept a parameter from the client that is set in the header.
In django 1.3 it was accessible by it's name, i.e:
{'HTTP_NAME_OF_PARAM':'value of parameter'}
And all was fine. However now, the header seems to look like this:
{'wsgi.input': <socket._fileobject object at 0x10ce09a50>}
So I need to get the data from this socket._fileobject in the header. How can I do that?
Thanks!

I shoud've mentioned that I use runserver for now, so I found this in the docs:
Note that runserver strips all headers with underscores in the name, so you won’t see them in META. This prevents header-spoofing based on ambiguity between underscores and dashes both being normalizing to underscores in WSGI environment variables. It matches the behavior of Web servers like Nginx and Apache 2.4+.
When changing the name to NAME-OF-PARAM it worked :)

Related

Django: Parameters in URLs .... which start with a slash

I use a regex for URL dispatching like described in the Django docs.
r'^remote/(?P<slug>[^/]+)/call_rfc/(?P<rfc_name>.+)$'
Unfortunately rfc_name can start with a slash!
Example:
https://example.com/remote/my_slug/call_rfc//MLK/FOO
The rfc_name is /MLK/FOO.
But this fails. Somewhere (I don't know yet if it is in the browser or in Django) the duplicate slash gets removed.
What is the best practice to handle URL parameters which can start with a slash?
It almost seems that you can consider the latest "slug" as a path. If that's the case, in your URL definition you can use path to represent that. You can have a look here to check if it helps.
path('remote/<slug:slug>/call_rfc/<path:rfc_name>', yourviewhere)
Or, you can perhaps write your custom path converter.

Django forms URLField allow empty scheme

I have a Django form that uses a 'forms.URLField' like local_url1 = URLField(label="First Local URL", required=False). If a user inputs something like 'https://www.google.com' then the field validates without error.
However, if the user puts 'www.google.com' the field fails validation and the user sees an error. This is because the layout of a URL is scheme://host:port/absolute_path and the failing URL is missing the scheme (e.g. https), which Django's URLFieldValidation expects.
I don't care if my users include the scheme and nor should my form. Unfortunately, the error from django is completely useless in indicating what is wrong, and I've had multiple users ask why it says to enter a valid URL. I'm also certain I've lost paying customers because of this.
Is there a way to have all the other validation of a URL take place, but ignore the fact that the scheme is missing? At the very least, can I change the error message to add something like "Did you include http?". I've attempted implementing my own URLField and URLFieldValidation, but unless that's the path I have to take, then that is a different StackOverflow question.
I'm using Django 1.7, by the way. Thanks for any help!
URL/URI scheme list to validate against. If not provided, the default
list is ['http', 'https', 'ftp', 'ftps']. As a reference, the IANA Web
site provides a full list of valid URI schemes.
If the valid URI schemes provided by IANA web are not what you are looking for, then I suggest you create your own field validator.
Remember that URLField is a subclass of the CharField. and since www.something.com is ok with you, then It's simple to add a regular expression to the regular CharField that checks if the pattern is correct or not.
A regular expression like this for example will validate against www and http://. so with or without http or https.
((?:https?\:\/\/|www\.)(?:[-a-z0-9]+\.)*[-a-z0-9]+.*)
www.google.com -- OK
http://www.google.com -- OK
https://www.google.com -- OK
http://google.com -- OK
https://google.com -- OK
However, this will not complain about blahwww.domain.com
so you might enhance it as you like.

Can I get the raw querystring in a django middleware?

Specifically my middleware is interested to differentiate between a GET request on:
/admin/app/model/?
/admin/app/model/
URL #1 was initiated with a dangling question mark.
From my experiments, django's HttpRequest swallows it up and I am unable to differentiate between the two. Is there a way to obtain the raw nonfiltered query string ?
? should be escaped as %3F. So, may be you should choose another symbol, without such problems?
This may not be possible. Typically a django application is served from behind the WSGI interface, by the time the request gets to django it's already been parsed into PATH_INFO (before the?) and QUERY_STRING (after the ?). When django runs get_full_path it's just concatenating those two things with a ? in the middle if needed.
It's also a bad idea: HTTP does not expect URLs to behave differently with a trailing ?, as that just means an empty set of parameters, which is the same thing that the absence of a ? means. As well as being confusing, this may cause interoperability problems, as a proxy or web browser might drop the trailing '?' in the expectation that it should have no effect.

Django's Satchmo and flatpages issue

I'm having a problem with configuring Flatpages in Satchmo. I've used them before, in a pure django app, but now it just doesn't work, returning 301 http error when I'm trying to enter a flatpage-configured site.
What I've done to configure it:
added the middleware "django.contrib.flatpages.middleware.FlatpageFallbackMiddleware" to MIDDLEWARE_CLASSES as last in the list,
configured example pages in admin module.
Simply what the docs say about flatpages config.
I'm feeling helpless. Don't know how could I debug this issue. Any thoughts on that?
And of course help appreciated.
Thanks to suggestion by Peter I've managed to narrow the problem to my urls.py file, for the satchmo shop.
The urlpatterns has only one entry:
(r'', 'django.views.generic.simple.redirect_to', {'url' : '/shop/'}),
This version does not work and moreover interfere with flatpages. But disabling flatpages from MIDDLEWARE_CLASSES and adding it to urls.py like the snippet below works:
(r'^(?P<url>.*)$', 'django.contrib.flatpages.views.flatpage'),
(r'', 'django.views.generic.simple.redirect_to', {'url' : '/shop/'}),
However next problem is with the redirection from / to /shop/. With the above config it results in infinite loop.
Perhaps you know the reason for that behavior (redirect overriding flatpage) and maybe You could suggest some working solution to this problem or what should be done with requests to /.
It returns 301? That's Page Moved Permanently (HttpResponsePermanentRedirect) and there are no references to that in the flatpages directory so I don't think it's coming from there. In fact there are only about 5 references to HttpResponsePermanentRedirect in all of the standard 1.1.1 release.
Possible approaches:
Comment out the FlatPages middleware and see if the error changes (I'm betting it won't).
Try changing the order of your MIDDLEWARE classes and see if things change.
When presenting a problem like this it's better to get very specific by showing the exact code from applicable portions of settings.py (or whatever) and by giving other things like precise URLs and the urls.py patterns you are trying to match.
Update:
OK, some random thoughts:
The pattern (r'^(?P<url>.*)$', 'django.contrib.flatpages.views.flatpage'), will match anything. Any patterns after it will never be seen.
flatpages doesn't work by being called directly, it does its magic in middleware. It looks for 404 responses (Page Not Found) and then looks to see if that path exists in its table. If so, it calls a view that renders the page, etc. etc. If it doesn't find a match it let's the 404 continue on through middleware processing.
The pattern (r'', 'django.views.generic.simple.redirect_to', {'url' : '/shop/'}), will match anything (I just tested it). If you want to match an empty path, use r('^$', etc.). This is the source of your infinite loop.
If you are new to regular expressions the Django urls.py file can seem like F*cking Magic. I recommend starting very simply and add one rule at a time. Do some quick tests to ensure that the new rule a) matches stuff you want it to match, and b) doesn't match stuff it shouldn't. In particular, make sure that some of the rules that occur later in the file are still reachable. In this case they wouldn't have been which should have raised a red flag.

Django url tag gives wrong values

My URLconf has:
url(r'^view-item$', 'appname.views.view_item', name='view-item'),
Now, if I go to http://myhost/path_to_django_app/view-item/, it works. However, {% url view-item %} returns '/view-item/'. Why is it doing this?
This problem occurred when I moved the application to a new server, so I'm guessing something must be configured wrong, but I don't even know where to look.
This may be due to the SCRIPT_NAME variable not being set correctly. The url tag will use this variable to compose the final absolute path to return.
You should check what request.META['SCRIPT_NAME'] is set to in one of your views. If it is not set correctly, then you may need to look into your backend configuration. If you are using mod_python, this usually involves making sure that django.root is set in the apache config. Check the installation docs for more info.
If you still can't get it to work, you can try adding this to settings.py:
FORCE_SCRIPT_NAME = '/path_to_django_app/'
The usual way to write your URl in django is with a trailing '/':
url(r'^view-item/$', 'appname.views.view_item', name='view-item')
or:
url(r'^view-item/', include('view.urls')),
Life will be much easier if you follow this convention.