- Author:
 - eternicode
 - Posted:
 - January 26, 2011
 - Language:
 - Python
 - Version:
 - 1.2
 - Score:
 - 0 (after 0 ratings)
 
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.
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29  | from django.http import HttpRequest
import inspect
class RequestFetchingMixin(object):
    def __new__(cls, *args, **kwargs):
        obj = object.__new__(cls, *args, **kwargs)
        f = inspect.currentframe()
        requests = []
        request = None
        backup_count = 0
        while not requests and f.f_back is not None and backup_count < 5:
            f = f.f_back
            for var, val in f.f_locals.iteritems():
                if isinstance(val, HttpRequest):
                    requests.append((var, val))
            backup_count += 1
        if not requests:
            request = None
        elif len(requests) == 1:
            request = requests[0][1]
        else:
            for var, val in requests:
                if var == 'request':
                    request = val
            if request is None:
                request = requests[0][1]
        obj.request = request
        return obj
 | 
More like this
- Add Toggle Switch Widget to Django Forms by OgliariNatan 1 month, 4 weeks ago
 - get_object_or_none by azwdevops 5 months, 2 weeks ago
 - Mask sensitive data from logger by agusmakmun 7 months, 2 weeks ago
 - Template tag - list punctuation for a list of items by shapiromatron 1 year, 9 months ago
 - JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 1 year, 9 months ago
 
Comments
Please login first before commenting.