I'm writing a wrapper function for Django's render_to_response() to add a CSRF processing.
The logic is:
def some_view (request)
dictionary = {'context_param': some_param}
dictionary.update(csrf(request))
# ... view code here
return render_to_response("a_template.html", dictionary)
render_to_response() has the following signature:
def render_to_response(*args, **kwargs)
I want to write transparent wrapper - just add some functionality (mentioned before) and leave other things as they are. I guess I should write someting like this:
def csrf_response (request, *args, **kwargs):
# Here I need to somehow extract dictionary from args or kwargs
if dictionary is None:
dictionary = {}
dictionary.update(csrf(request))
# And here I somehow need to pass dictionary into render_to_response() fot the furher processing
return render_to_response(*args, **kwargs)
So question is - what is the best practice for extracting needed parameter from args/kwargs, (then changing it) and passing it further?
BTW code of render_to_response() seemed me a bit strange. Here it is:
def render_to_response(*args, **kwargs):
"""
Returns a HttpResponse whose content is filled with the result of calling
django.template.loader.render_to_string() with the passed arguments.
"""
httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
What if someone call it with all positional arguments, so kwargs will be empty, but mimetype
parameter will be specified as a last positional argument? Looks like in that case its behavior would be wrong.
Because of how render_to_response
is implemented, the only way to specify mimetype is by using a named argument. Anything passed as a positional argument will be passed on to loader.render_to_string
.
The methodology for how to go about extracting certain arguments and passing on others really depends on what you're doing. There's no one "correct" way to always do it. Naturally, different authors have their own preferred conventions.
In the place of your comment # Here I need to somehow extract dictionary from args or kwargs
you can use kwargs directly as a dictionary, and args as a tuple, because that's exactly what they are. For the args, you have no choice but to assert (i.e. assume) the meaning of the value in each position.
I personally prefer that if you are writing code that knows the values of certain arguments, they should be declared in the signature, like so:
def spam(session, name, *args, clear=True, **kwargs):
# do something with session, name, clear
return eggs(name, *args, **kwargs) # if eggs requires name
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With