from django.shortcuts import render_to_response from django import forms from django.template import RequestContext from django.db.models import signals as signalmodule from django.http import HttpResponse from django.utils import simplejson __all__ = ['render_to', 'signals', 'ajax_request', 'autostrip'] try: from functools import wraps except ImportError: def wraps(wrapped, assigned=('__module__', '__name__', '__doc__'), updated=('__dict__',)): def inner(wrapper): for attr in assigned: setattr(wrapper, attr, getattr(wrapped, attr)) for attr in updated: getattr(wrapper, attr).update(getattr(wrapped, attr, {})) return wrapper return inner def render_to(template=None, mimetype=None): """ Decorator for Django views that sends returned dict to render_to_response function. Template name can be decorator parameter or TEMPLATE item in returned dictionary. RequestContext always added as context instance. If view doesn't return dict then decorator simply returns output. Parameters: - template: template name to use - mimetype: content type to send in response headers Examples: # 1. Template name in decorator parameters @render_to('template.html') def foo(request): bar = Bar.object.all() return {'bar': bar} # equals to def foo(request): bar = Bar.object.all() return render_to_response('template.html', {'bar': bar}, context_instance=RequestContext(request)) # 2. Template name as TEMPLATE item value in return dictionary. if TEMPLATE is given then its value will have higher priority than render_to argument. @render_to() def foo(request, category): template_name = '%s.html' % category return {'bar': bar, 'TEMPLATE': template_name} #equals to def foo(request, category): template_name = '%s.html' % category return render_to_response(template_name, {'bar': bar}, context_instance=RequestContext(request)) """ def renderer(function): @wraps(function) def wrapper(request, *args, **kwargs): output = function(request, *args, **kwargs) if not isinstance(output, dict): return output tmpl = output.pop('TEMPLATE', template) return render_to_response(tmpl, output, \ context_instance=RequestContext(request), mimetype=mimetype) return wrapper return renderer class Signals(object): ''' Convenient wrapper for working with Django's signals (or any other implementation using same API). Example of usage:: # connect to registered signal @signals.post_save(sender=YourModel) def sighandler(instance, **kwargs): pass # connect to any signal signals.register_signal(siginstance, signame) # and then as in example above or @signals(siginstance, sender=YourModel) def sighandler(instance, **kwargs): pass In any case defined function will remain as is, without any changes. (c) 2008 Alexander Solovyov, new BSD License ''' def __init__(self): self._signals = {} # register all Django's default signals for k, v in signalmodule.__dict__.iteritems(): # that's hardcode, but IMHO it's better than isinstance if not k.startswith('__') and k != 'Signal': self.register_signal(v, k) def __getattr__(self, name): return self._connect(self._signals[name]) def __call__(self, signal, **kwargs): def inner(func): signal.connect(func, **kwargs) return func return inner def _connect(self, signal): def wrapper(**kwargs): return self(signal, **kwargs) return wrapper def register_signal(self, signal, name): self._signals[name] = signal signals = Signals() class JsonResponse(HttpResponse): """ HttpResponse descendant, which return response with ``application/json`` mimetype. """ def __init__(self, data): super(JsonResponse, self).__init__(content=simplejson.dumps(data), mimetype='application/json') def ajax_request(func): """ If view returned serializable dict, returns JsonResponse with this dict as content. example: @ajax_request def my_view(request): news = News.objects.all() news_titles = [entry.title for entry in news] return {'news_titles': news_titles} """ @wraps(func) def wrapper(request, *args, **kwargs): response = func(request, *args, **kwargs) if isinstance(response, dict): return JsonResponse(response) else: return response return wrapper def autostrip(cls): """ strip text fields before validation example: class PersonForm(forms.Form): name = forms.CharField(min_length=2, max_length=10) email = forms.EmailField() PersonForm = autostrip(PersonForm) #or you can use @autostrip in python >= 2.6 Author: nail.xx """ fields = [(key, value) for key, value in cls.base_fields.iteritems() if isinstance(value, forms.CharField)] for field_name, field_object in fields: def get_clean_func(original_clean): return lambda value: original_clean(value and value.strip()) clean_func = get_clean_func(getattr(field_object, 'clean')) setattr(field_object, 'clean', clean_func) return cls