Permalink
Browse files

added django annoying

  • Loading branch information...
1 parent 889f491 commit a34b87dd7fa0ac101502cb934f23e6e74078a747 @bmac committed Oct 25, 2010
View
@@ -0,0 +1 @@
+Anderson <self.anderson@gmail.com>
View
@@ -0,0 +1,5 @@
+Installation instruction:
+
+* Copy annoying directory to your django project or put in on PYTHONPATH.
+
+That's it.
View
@@ -0,0 +1,10 @@
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
View
@@ -0,0 +1,7 @@
+Django Annoying Application
+========================
+
+This is django application that try to eliminate annoying things in Django framework.
+
+For installation instructions see the file "INSTALL.txt" in this
+directory. You need last development version of django to use this application.
View
No changes.
View
@@ -0,0 +1,194 @@
+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="text/html"):
+ """
+ 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
+
View
@@ -0,0 +1,5 @@
+class Redirect(Exception):
+ def __init__(self, *args, **kwargs):
+ self.args = args
+ self.kwargs = kwargs
+
View
@@ -0,0 +1,69 @@
+from django.db import models
+from django.db.models import OneToOneField
+from django.utils import simplejson as json
+from django.core.serializers.json import DjangoJSONEncoder
+from django.db.models.fields.related import SingleRelatedObjectDescriptor
+
+
+class AutoSingleRelatedObjectDescriptor(SingleRelatedObjectDescriptor):
+ def __get__(self, instance, instance_type=None):
+ try:
+ return super(AutoSingleRelatedObjectDescriptor, self).__get__(instance, instance_type)
+ except self.related.model.DoesNotExist:
+ obj = self.related.model(**{self.related.field.name: instance})
+ obj.save()
+ return obj
+
+
+class AutoOneToOneField(OneToOneField):
+ '''
+ OneToOneField creates related object on first call if it doesnt exists yet.
+ Use it instead of original OneToOne field.
+
+ example:
+
+ class MyProfile(models.Model):
+ user = AutoOneToOneField(User, primary_key=True)
+ home_page = models.URLField(max_length=255, blank=True)
+ icq = models.IntegerField(max_length=255, null=True)
+ '''
+ def contribute_to_related_class(self, cls, related):
+ setattr(cls, related.get_accessor_name(), AutoSingleRelatedObjectDescriptor(related))
+
+
+class JSONField(models.TextField):
+ """
+ JSONField is a generic textfield that neatly serializes/unserializes
+ JSON objects seamlessly.
+ Django snippet #1478
+
+ example:
+ class Page(models.Model):
+ data = JSONField(blank=True, null=True)
+
+
+ page = Page.objects.get(pk=5)
+ page.data = {'title': 'test', 'type': 3}
+ page.save()
+ """
+
+ __metaclass__ = models.SubfieldBase
+
+ def to_python(self, value):
+ if value == "":
+ return None
+
+ try:
+ if isinstance(value, basestring):
+ return json.loads(value)
+ except ValueError:
+ pass
+ return value
+
+ def get_db_prep_save(self, value):
+ if value == "":
+ return None
+ if isinstance(value, dict):
+ value = json.dumps(value, cls=DjangoJSONEncoder)
+ return super(JSONField, self).get_db_prep_save(value)
+
View
@@ -0,0 +1,32 @@
+from django.shortcuts import _get_queryset
+from django.conf import settings
+
+
+def get_object_or_None(klass, *args, **kwargs):
+ """
+ Uses get() to return an object or None if the object does not exist.
+
+ klass may be a Model, Manager, or QuerySet object. All other passed
+ arguments and keyword arguments are used in the get() query.
+
+ Note: Like with get(), an MultipleObjectsReturned will be raised if more than one
+ object is found.
+ """
+ queryset = _get_queryset(klass)
+ try:
+ return queryset.get(*args, **kwargs)
+ except queryset.model.DoesNotExist:
+ return None
+
+
+
+def get_config(key, default):
+ """
+ Get settings from django.conf if exists,
+ return default value otherwise
+
+ example:
+
+ ADMIN_EMAIL = get_config('ADMIN_EMAIL', 'default@email.com')
+ """
+ return getattr(settings, key, default)
View
@@ -0,0 +1,32 @@
+import re
+
+from django.conf import settings
+from django.views.static import serve
+from django.shortcuts import redirect
+
+from .exceptions import Redirect
+
+
+class StaticServe(object):
+ """
+ Django middleware for serving static files instead of using urls.py
+ """
+ regex = re.compile(r'^%s(?P<path>.*)$' % settings.MEDIA_URL)
+
+ def process_request(self, request):
+ if settings.DEBUG:
+ match = self.regex.search(request.path)
+ if match:
+ return serve(request, match.group(1), settings.MEDIA_ROOT)
+
+
+class RedirectMiddleware(object):
+ """
+ You must add this middleware to MIDDLEWARE_CLASSES list,
+ to make work Redirect exception. All arguments passed to
+ Redirect will be passed to django built in redirect function.
+ """
+ def process_exception(self, request, exception):
+ if not isinstance(exception, Redirect):
+ return
+ return redirect(*exception.args, **exception.kwargs)
No changes.
@@ -0,0 +1,14 @@
+import django
+from django import template
+
+from smart_if import smart_if
+
+
+register = template.Library()
+
+
+try:
+ if int(django.get_version()[-5:]) < 11806:
+ register.tag('if', smart_if)
+except ValueError:
+ pass
Oops, something went wrong.

0 comments on commit a34b87d

Please sign in to comment.