5

I understand that the standard way of accessing named url parameters in a custom get_context_data() method is through self.kwargs.

However, the self.kwargs syntax becomes awkward, especially when handling a significant number of parameters. So, I've been resorting to something like this at the top of every get_context_data() method -- just to get easy-to-handle local variables:

def get_context_data(self, **kwargs):
    var1, var2, var3, var4, var5 = [self.kwargs[x] for x in ['var1', 'var2', 'var3', 'var4', 'var5']]
    # do stuff with var1, var2, ...
    # instead of self.kwargs['var1'], self.kwargs['var2'], ...

This is ugly and a pain, but it ultimately makes things a lot easier to work with and read.

Is there a simple way to clean it up and get named parameters into local variables? Short of overriding the get() method, subclassing Django's generic views, etc.? I suspect I'm just missing some extremely basic, fundamental python concept here.

Here is the default get() method that calls get_context_data() in case it's helpful to reference here:

def get(self, request, *args, **kwargs):
    context = self.get_context_data(**kwargs)
    return self.render_to_response(context)

UPDATE:

My mistake, the calling get() method is actually as follows (The generic FormView is being subclassed in this case). Unfortunately the kwargs that are passed into get_context_data() are not the same as self.kwargs:

def get(self, request, *args, **kwargs):
    form_class = self.get_form_class()
    form = self.get_form(form_class)
    return self.render_to_response(self.get_context_data(form=form))

Many thanks!

tino
  • 4,780
  • 5
  • 24
  • 30
  • No, you are not missing any fundamental concept. But reading from dicts can indeed get on one's nerves. That is why there are a bunch of packages at PyPI that convert a ``dict`` with only ``str`` keys into an object with accordingly named (virtual) attributes. I sometimes use [``dictns``](https://pypi.python.org/pypi/dictns) for that purpose. Nice! – Lutz Prechelt Apr 07 '16 at 17:13

1 Answers1

4

If kwargs passed to get_context_data is the same as self.kwargs, You could do this:

def get_context_data(self, var1, var2, var3, var4, var5, **kwargs):
    # do stuff with var1, var2, ...

EDIT: you could override the get method to pass the kwargs in. I know its not elegant, but it would work. You could make a mixin to use in multiple classes.

def get(self, request, *args, **kwargs):
    form_class = self.get_form_class()
    form = self.get_form(form_class)
    return self.render_to_response(self.get_context_data(form=form, **kwargs))

Other than that, I really can't think of a better way. Your original solution might be best. I usually just access self.kwargs['...'] directly.

jproffitt
  • 6,225
  • 30
  • 42
  • 1
    Thanks for the reply! Unfortunately this doesn't work with `FormView`, where the kwargs passed are not the same as `self.kwargs`. I updated the question. – tino Nov 13 '13 at 00:09
  • Ah, well I can't think of a great way then. I did edit my answer with some more thoughts though. Sorry I can't help any more than that. – jproffitt Nov 13 '13 at 00:43
  • No worries, and thanks for taking a look! Your solution works for, say, `TemplateView` where kwargs == self.kwargs. This whole issue is just a minor gripe on my part anyways. – tino Nov 13 '13 at 00:51
  • P.S. You'd have to override both `form_invalid()` _and_ `get()` just to get `FormView` working this way. Heh, what a mess. I wonder why those methods don't pass kwargs to `get_context_data()`. – tino Nov 13 '13 at 01:01
  • Yes I figured there would be another method to override. I think it's too much hassle. If I were you I would just stick to your original solution. Or maybe create another method which you call from get_context_data. And pass self.kwargs to that new method. I usually don't like to do too much processing in get_context_data anyway. – jproffitt Nov 13 '13 at 01:14
  • You're totally right -- I should pull all the processing into a new method. And I think I can live with the list comprehension bit to stuff kwargs into local variables. Thanks again! – tino Nov 13 '13 at 01:41