Login

RestMiddleware - automatically load objects from url-path

Author:
dhke
Posted:
August 27, 2014
Language:
Python
Version:
1.6
Tags:
middleware urls models
Score:
0 (after 0 ratings)

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

  1. Automating URLs by jorjun 6 years ago
  2. Automatically strip CharFields by pietras 5 years, 11 months ago
  3. Loading initial data per model at table creation (useful with migrations) by GigiusB 11 months, 4 weeks ago
  4. Mixin for named URL WizardViews with one form on the frontpage by jezdez 3 years, 4 months ago
  5. Image Standarization by garcia_marc 7 years, 2 months ago

Comments

Please login first before commenting.