Automatically load models when their IDs appear in the URL-path.
See docstrings for usage and example.
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | class RestMiddleware(object):
"""
generic middleware that looks up model
ids specified on the url path and stores it
in a ``models'' dictionary in the request object.
Accepts a ``model_map'' dictionary that specifies
the mapping between path variable names ``(?P<name>)''
and corresponding model managers.
Example:
--------
model_map = {
'session': models.GameSession.objects,
}
url(r'^session/(?P<session>)/operation$) will lookup
the appropriate `` GameSession'' object using
the ``GameSession'''s model manager and stores
it at ``request.models['session']''. A ``None''
object will be stored if the model lookup was not
successful.
"""
def __init__(self, model_map=None, require_login=True, prefetch_related=None, select_related=None):
self.model_map = model_map if model_map else {}
self.prefetch_related = prefetch_related if prefetch_related else {}
self.select_related = select_related if select_related else {}
self.require_login = bool(require_login)
def process_view(self, request, view_func, view_args, view_kwargs):
if self.require_login and (not hasattr(request, 'user') or not request.user.is_authenticated()):
return redirect_to_login(request.get_full_path())
else:
if not hasattr(request, 'models'):
request.models = {}
for view_arg, pk in view_kwargs.iteritems():
manager = self.model_map.get(view_arg)
prefetch_related = self.prefetch_related.get(view_arg)
if prefetch_related:
manager = manager.prefetch_related(*prefetch_related)
select_related = self.select_related.get(view_arg)
if select_related:
manager = manager.select_related(*select_related)
if manager:
try:
obj = manager.get(pk=pk)
request.models[view_arg] = obj
except ObjectDoesNotExist:
pass
class Game1RestMiddleware(RestMiddleware):
def __init__(self, require_login=True, prefetch_related=None, select_related=None):
model_map = {
'session': models.GameSession.objects,
'collectible': models.Collectible.objects.select_subclasses(),
'category': models.Category.objects,
'chest': models.TreasureChest.objects,
'message': models.Message.objects,
'image': models.Image.objects,
}
super(Game1RestMiddleware, self).__init__(
model_map=model_map,
require_login=require_login,
prefetch_related=prefetch_related,
select_related=select_related
)
def process_view(self, request, view_func, view_args, view_kwargs):
result = super(Game1RestMiddleware, self).process_view(request, view_func, view_args, view_kwargs)
try:
rmodels = request.models
except AttributeError:
request.models = {}
rmodels = request.models
# pull the game session from
# the chest or collectible if possible
#
# do not do this for other models, i.e. do not pull the chest from
# a deposited collectible
if not 'session' in rmodels:
chest = rmodels.get('chest')
if chest and chest.session:
rmodels['session'] = chest.session
if not 'session' in rmodels:
collectible = rmodels.get('collectible')
if collectible and collectible.session:
rmodels['session'] = collectible.session
return result
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 8 months ago
Comments
Please login first before commenting.