Long story short:
* Django lets you call functions in templates, but you can't pass any parameters.
* Sometimes you need to use the request object to perform certain tasks, such as determining whether the current user has permission to do something.
* The recommended approach is to call functions that require parameters in the view, and then pass the results as variables in the context. This sometimes feels a bit overkill.
* Creating a templatetag to call any function with any parameter will definitely break the intention for not letting functions to be called with parameters in templates.
* So, what if we could tell django to inject the request into certain functions? That's what this decorator is for.
For instance, suppose you have a model:
class SomeModel(models.Model):
...
def current_user_can_do_something(self, request):
...some logic here using request...
You could use the decorator like this:
class SomeModel(models.Model):
...
@inject_request
def current_user_can_do_something(self, request=None):
...some logic here using request...
And in the template go straight to:
{{ somemodel_instance.current_user_can_do_something }}
So that the decorator would perform some operations to find the request in the frame tree and inject it if found. The assertions are intented to make sure things will work even if the request cannot be found, so that the coder may program defensively.
Позволяет получить типизированный словарь из входных параметров.
Может быть использован, например, для дальнейшей передаче параметров в objects.filter(**rez).
I thought it would be useful to have a `get_addr()` method available on request objects, similar to the `get_host()` provided by Django. This middleware will add a `get_addr()` method to requests which uses the `X-Forwarded-For` header (useful if you're behind a proxy) if it's present and you have the `USE_X_FORWARDED_FOR` header set to `True` (default is `False`) and otherwise will use the `REMOTE_ADDR` environment variable. Note that if you are *not* behind a proxy and have `USE_X_FORWARDED_FOR` set to `True`, then clients can spoof their IP by simply setting the `X-Forwarded-For header`.
Simple logging middleware that captures the following:
* remote address (whether proxied or direct)
* if authenticated, then user email address
* request method (GET/POST etc)
* request full path
* response status code (200, 404 etc)
* content length
* request process time
* If DEBUG=True, also logs SQL query information - number of queries and how long they took
If your application server is behind a proxy, `request.META["REMOTE_ADDR"]` will likely return the proxy server's IP, not the client's IP. The proxy server will usually provide the client's IP in the `HTTP_X_FORWARDED_FOR` header. This util function checks both headers. I use it behind Amazon's Elastic Load Balancer (ELB).
The tag generates a parameter string in form '?param1=val1¶m2=val2'.
The parameter list is generated by taking all parameters from current
request.GET and optionally overriding them by providing parameters to the tag.
This is a cleaned up version of http://djangosnippets.org/snippets/2105/. It
solves a couple of issues, namely:
* parameters are optional
* parameters can have values from request, e.g. request.GET.foo
* native parsing methods are used for better compatibility and readability
* shorter tag name
Usage: place this code in your appdir/templatetags/add_get_parameter.py
In template:
{% load add_get_parameter %}
<a href="{% add_get param1='const' param2=variable_in_context %}">
Link with modified params
</a>
It's required that you have 'django.core.context_processors.request' in
TEMPLATE_CONTEXT_PROCESSORS
More a proof of concept than anything, this mixin addresses a perceived "shortcoming" of django forms: the inability to interact with the current request, and specifically the "current user".
Usage:
class SomeForm(forms.Form, RequestFetchingMixin):
# fields...
def __init__(self, *args, **kwargs):
if self.request:
# interact with self.request?
super(SomeForm, self).__init__(*args, **kwargs)
if self.request:
# more interaction
def clean(self):
if self.request:
# blah blah self.request.user blah
Notes:
* This reaches "into the past" to pull an existing HttpRequest object, regardless of what name it was bound to, into "the present".
* If multiple requests are found (what on earth are you doing??), the one bound to "request" (or the first one found, if that's not available) will be used.
* By default it goes up to 5 frames back before giving up, but that can obviously be changed if you think you need it.
* This won't work everywhere. self.request is guaranteed to be present, but may be None.
* Just because you have a self.request doesn't mean self.request.user will be a valid user. This is subject to all the rules that a regular view's request is subject to (because it *is* a regular view's request!)
* This isn't magic; it's just python.
Testing low-level functionality sometimes requires a WSGIRequest object. An example of this is testing template tags.
This will monkey-patch the test Client object to return WSGIRequest objects
Normal Django behavior:
>>> client.get('/')
<HttpResponse >
With this code, get the request object:
>>> client.request_from.get('/')
<WSGIRequest >
Installation:
For this to work, you simply need to import the contents of this file.
If you name this file `clientrequestpatch.py`, do this inside your Django tests.
from django.test.testcases import TestCase
from myproject.test import clientrequestpatch
This is an update to Simon Willison's snippet http://djangosnippets.org/snippets/963/, along with one of the comments in that snippet.
This class lets you create a Request object that's gone through all the middleware. Suitable for unit testing when you need to modify something on the request directly, or pass in a mock object.
(note: see http://labix.org/mocker for details on how to mock requests for testing)
Example on how to use:
from django.test import TestCase
from yourapp import your_view
from yourutils import RequestFactory
class YourTestClass(TestCase):
def setUp(self):
pass
def tearDown(self):
pass
# Create your own request, which you can modify, instead of using self.client.
def test_your_view(self):
# Create your request object
rf = RequestFactory()
request = rf.get('/your-url-here/')
# ... modify the request to your liking ...
response = your_view(request)
self.assertEqual(response.status_code, 200)
Suggestions/improvements are welcome. :)
When you neeed to do redirect and request object is not available, you can do it with exception.
Put exception handler somewhere request is available, for example to middleware or ModelAdmin.
Raise exception, where request is not available.
Mechanism to obtain a `request.user` object without the `request` object itself. Requires `LocalUserMiddleware` in `MIDDLEWARE_CLASSES` settings variable.
**Important**: works under assumption that within a web server each request is handled by a separate thread (as for example in the Apache HTTP server).
**Beware**: [security threat](http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser), although ["thread locals only appears to be a security threat if a system has already been seriously compromised, at which point there'd be easier attacks to execute"](http://groups.google.com/group/django-users/browse_thread/thread/e7af359d7d183e04).
**Dev note**: works fine with one-threaded Django's development server, each request resets current user; no worries 'bout many media requests - they won't (at least shouldn't) be using Django on the production server.
**Ref**: originally found in the gatekeeper app.
This template tag attempts to get specific GET variables from request.GET. If such variables exist, it shows them as a query string (with optional "include_ampersand" mode when it puts an "&" at the end if there is a result string, or a "?" if there's none: it is used when you need to add a new variable to the query string) or as hidden input fields ("html_form" mode).