Django

Code

Changeset 7173

Show
Ignore:
Timestamp:
02/28/08 09:48:19 (9 months ago)
Author:
mtredinnick
Message:

queryset-refactor: Merged from trunk up to [7168].

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/queryset-refactor/django/contrib/admin/views/decorators.py

    r7136 r7173  
     1import base64 
     2import md5 
     3import cPickle as pickle 
     4try: 
     5    from functools import wraps 
     6except ImportError: 
     7    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback. 
     8 
    19from django import http, template 
    210from django.conf import settings 
     
    614from django.utils.translation import ugettext_lazy, ugettext as _ 
    715from django.utils.safestring import mark_safe 
    8 import base64, md5 
    9 import cPickle as pickle 
    1016 
    1117ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.") 
     
    105111                return _display_login_form(request, ERROR_MESSAGE) 
    106112 
    107     return _checklogin 
     113    return wraps(view_func)(_checklogin) 
  • django/branches/queryset-refactor/django/contrib/auth/decorators.py

    r6690 r7173  
     1try: 
     2    from functools import wraps, update_wrapper 
     3except ImportError: 
     4    from django.utils.functional import wraps, update_wrapper  # Python 2.3, 2.4 fallback. 
     5 
    16from django.contrib.auth import REDIRECT_FIELD_NAME 
    27from django.http import HttpResponseRedirect 
     
    5257        self.login_url = login_url 
    5358        self.redirect_field_name = redirect_field_name 
    54         self.__name__ = view_func.__name__ 
     59        update_wrapper(self, view_func) 
    5560         
    5661    def __get__(self, obj, cls=None): 
  • django/branches/queryset-refactor/django/core/handlers/base.py

    r7086 r7173  
    110110            return http.HttpResponseForbidden('<h1>Permission denied</h1>') 
    111111        except SystemExit: 
    112             pass # See http://code.djangoproject.com/ticket/1023 
     112            # Allow sys.exit() to actually exit. See tickets #1023 and #4701 
     113            raise 
    113114        except: # Handle everything else, including SuspiciousOperation, etc. 
    114115            # Get the exception info now, in case another exception is thrown later. 
  • django/branches/queryset-refactor/django/db/backends/postgresql/operations.py

    r7152 r7173  
    3030    def field_cast_sql(self, db_type): 
    3131        if db_type == 'inet': 
    32             return 'CAST(%s AS TEXT)' 
     32            return 'HOST(%s)' 
    3333        return '%s' 
    3434 
  • django/branches/queryset-refactor/django/db/models/fields/related.py

    r7171 r7173  
    2424pending_lookups = {} 
    2525 
    26 def add_lookup(rel_cls, field): 
    27     name = field.rel.to 
    28     module = rel_cls.__module__ 
    29     key = (module, name) 
    30     # Has the model already been loaded? 
    31     # If so, resolve the string reference right away 
    32     model = get_model(rel_cls._meta.app_label, field.rel.to, False) 
     26def add_lazy_relation(cls, field, relation): 
     27    """ 
     28    Adds a lookup on ``cls`` when a related field is defined using a string, 
     29    i.e.:: 
     30     
     31        class MyModel(Model): 
     32            fk = ForeignKey("AnotherModel") 
     33             
     34    This string can be: 
     35     
     36        * RECURSIVE_RELATIONSHIP_CONSTANT (i.e. "self") to indicate a recursive 
     37          relation. 
     38           
     39        * The name of a model (i.e "AnotherModel") to indicate another model in 
     40          the same app. 
     41           
     42        * An app-label and model name (i.e. "someapp.AnotherModel") to indicate 
     43          another model in a different app. 
     44           
     45    If the other model hasn't yet been loaded -- almost a given if you're using 
     46    lazy relationships -- then the relation won't be set up until the 
     47    class_prepared signal fires at the end of model initialization. 
     48    """ 
     49    # Check for recursive relations 
     50    if relation == RECURSIVE_RELATIONSHIP_CONSTANT: 
     51        app_label = cls._meta.app_label 
     52        model_name = cls.__name__ 
     53     
     54    else: 
     55        # Look for an "app.Model" relation 
     56        try: 
     57            app_label, model_name = relation.split(".") 
     58        except ValueError: 
     59            # If we can't split, assume a model in current app 
     60            app_label = cls._meta.app_label 
     61            model_name = relation 
     62     
     63    # Try to look up the related model, and if it's already loaded resolve the 
     64    # string right away. If get_model returns None, it means that the related 
     65    # model isn't loaded yet, so we need to pend the relation until the class  
     66    # is prepared. 
     67    model = get_model(app_label, model_name, False) 
    3368    if model: 
    3469        field.rel.to = model 
    35         field.do_related_class(model, rel_cls) 
     70        field.do_related_class(model, cls) 
    3671    else: 
    37         # Mark the related field for later lookup 
    38         pending_lookups.setdefault(key, []).append((rel_cls, field)) 
    39  
     72        key = (app_label, model_name) 
     73        value = (cls, field) 
     74        pending_lookups.setdefault(key, []).append(value) 
     75     
    4076def do_pending_lookups(sender): 
    41     other_cls = sender 
    42     key = (other_cls.__module__, other_cls.__name__) 
    43     for rel_cls, field in pending_lookups.setdefault(key, []): 
    44         field.rel.to = other_cls 
    45         field.do_related_class(other_cls, rel_cls) 
     77    """ 
     78    Handle any pending relations to the sending model. Sent from class_prepared. 
     79    """ 
     80    key = (sender._meta.app_label, sender.__name__) 
     81    for cls, field in pending_lookups.pop(key, []): 
     82        field.rel.to = sender 
     83        field.do_related_class(sender, cls) 
    4684 
    4785dispatcher.connect(do_pending_lookups, signal=signals.class_prepared) 
     
    67105        other = self.rel.to 
    68106        if isinstance(other, basestring): 
    69             if other == RECURSIVE_RELATIONSHIP_CONSTANT: 
    70                 self.rel.to = cls.__name__ 
    71             add_lookup(cls, self) 
     107            add_lazy_relation(cls, self, other) 
    72108        else: 
    73109            self.do_related_class(other, cls) 
  • django/branches/queryset-refactor/django/http/__init__.py

    r6954 r7173  
    172172        return result 
    173173 
    174     def __deepcopy__(self, memo={}): 
     174    def __deepcopy__(self, memo): 
    175175        import copy 
    176176        result = self.__class__('', mutable=True) 
     
    224224    def copy(self): 
    225225        "Returns a mutable copy of this object." 
    226         return self.__deepcopy__(
     226        return self.__deepcopy__({}
    227227 
    228228    def urlencode(self): 
  • django/branches/queryset-refactor/django/template/defaultfilters.py

    r7086 r7173  
    33import re 
    44import random as random_module 
     5try: 
     6    from functools import wraps 
     7except ImportError: 
     8    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback. 
    59 
    610from django.template import Variable, Library 
     
    3640        if hasattr(func, attr): 
    3741            setattr(_dec, attr, getattr(func, attr)) 
    38     return _dec 
     42    return wraps(func)(_dec) 
    3943 
    4044################### 
  • django/branches/queryset-refactor/django/utils/decorators.py

    r5631 r7173  
    22 
    33import types 
     4try: 
     5    from functools import wraps 
     6except ImportError: 
     7    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback. 
    48 
    59def decorator_from_middleware(middleware_class): 
     
    5458                    return result 
    5559            return response 
    56         return _wrapped_view 
     60        return wraps(view_func)(_wrapped_view) 
    5761    return _decorator_from_middleware 
  • django/branches/queryset-refactor/django/utils/functional.py

    r6597 r7173  
     1# License for code in this file that was taken from Python 2.5. 
     2 
     3# PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 
     4# -------------------------------------------- 
     5# 
     6# 1. This LICENSE AGREEMENT is between the Python Software Foundation 
     7# ("PSF"), and the Individual or Organization ("Licensee") accessing and 
     8# otherwise using this software ("Python") in source or binary form and 
     9# its associated documentation. 
     10# 
     11# 2. Subject to the terms and conditions of this License Agreement, PSF 
     12# hereby grants Licensee a nonexclusive, royalty-free, world-wide 
     13# license to reproduce, analyze, test, perform and/or display publicly, 
     14# prepare derivative works, distribute, and otherwise use Python 
     15# alone or in any derivative version, provided, however, that PSF's 
     16# License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 
     17# 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation; 
     18# All Rights Reserved" are retained in Python alone or in any derivative 
     19# version prepared by Licensee. 
     20# 
     21# 3. In the event Licensee prepares a derivative work that is based on 
     22# or incorporates Python or any part thereof, and wants to make 
     23# the derivative work available to others as provided herein, then 
     24# Licensee hereby agrees to include in any such work a brief summary of 
     25# the changes made to Python. 
     26# 
     27# 4. PSF is making Python available to Licensee on an "AS IS" 
     28# basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR 
     29# IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND 
     30# DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS 
     31# FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT 
     32# INFRINGE ANY THIRD PARTY RIGHTS. 
     33# 
     34# 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 
     35# FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS 
     36# A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, 
     37# OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 
     38# 
     39# 6. This License Agreement will automatically terminate upon a material 
     40# breach of its terms and conditions. 
     41# 
     42# 7. Nothing in this License Agreement shall be deemed to create any 
     43# relationship of agency, partnership, or joint venture between PSF and 
     44# Licensee.  This License Agreement does not grant permission to use PSF 
     45# trademarks or trade name in a trademark sense to endorse or promote 
     46# products or services of Licensee, or any third party. 
     47# 
     48# 8. By copying, installing or otherwise using Python, Licensee 
     49# agrees to be bound by the terms and conditions of this License 
     50# Agreement. 
     51 
     52 
    153def curry(_curried_func, *args, **kwargs): 
    254    def _curried(*moreargs, **morekwargs): 
    355        return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs)) 
    456    return _curried 
     57 
     58### Begin from Python 2.5 functools.py ######################################## 
     59 
     60# Summary of changes made to the Python 2.5 code below: 
     61#   * swapped ``partial`` for ``curry`` to maintain backwards-compatibility 
     62#     in Django. 
     63#   * Wrapped the ``setattr`` call in ``update_wrapper`` with a try-except 
     64#     block to make it compatible with Python 2.3, which doesn't allow 
     65#     assigning to ``__name__``. 
     66 
     67# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation. 
     68# All Rights Reserved. 
     69 
     70############################################################################### 
     71 
     72# update_wrapper() and wraps() are tools to help write 
     73# wrapper functions that can handle naive introspection 
     74 
     75WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__') 
     76WRAPPER_UPDATES = ('__dict__',) 
     77def update_wrapper(wrapper, 
     78                   wrapped, 
     79                   assigned = WRAPPER_ASSIGNMENTS, 
     80                   updated = WRAPPER_UPDATES): 
     81    """Update a wrapper function to look like the wrapped function 
     82 
     83       wrapper is the function to be updated 
     84       wrapped is the original function 
     85       assigned is a tuple naming the attributes assigned directly 
     86       from the wrapped function to the wrapper function (defaults to 
     87       functools.WRAPPER_ASSIGNMENTS) 
     88       updated is a tuple naming the attributes off the wrapper that 
     89       are updated with the corresponding attribute from the wrapped 
     90       function (defaults to functools.WRAPPER_UPDATES) 
     91    """ 
     92    for attr in assigned: 
     93        try: 
     94            setattr(wrapper, attr, getattr(wrapped, attr)) 
     95        except TypeError: # Python 2.3 doesn't allow assigning to __name__. 
     96            pass 
     97    for attr in updated: 
     98        getattr(wrapper, attr).update(getattr(wrapped, attr)) 
     99    # Return the wrapper so this can be used as a decorator via curry() 
     100    return wrapper 
     101 
     102def wraps(wrapped, 
     103          assigned = WRAPPER_ASSIGNMENTS, 
     104          updated = WRAPPER_UPDATES): 
     105    """Decorator factory to apply update_wrapper() to a wrapper function 
     106 
     107       Returns a decorator that invokes update_wrapper() with the decorated 
     108       function as the wrapper argument and the arguments to wraps() as the 
     109       remaining arguments. Default arguments are as for update_wrapper(). 
     110       This is a convenience function to simplify applying curry() to 
     111       update_wrapper(). 
     112    """ 
     113    return curry(update_wrapper, wrapped=wrapped, 
     114                 assigned=assigned, updated=updated) 
     115 
     116### End from Python 2.5 functools.py ########################################## 
    5117 
    6118def memoize(func, cache, num_args): 
     
    19131        cache[mem_args] = result 
    20132        return result 
    21     return wrapper 
     133    return wraps(func)(wrapper) 
    22134 
    23135class Promise(object): 
     
    111223        return __proxy__(args, kw) 
    112224 
    113     return __wrapper__ 
     225    return wraps(func)(__wrapper__) 
    114226 
    115227def allow_lazy(func, *resultclasses): 
     
    127239            return func(*args, **kwargs) 
    128240        return lazy(func, *resultclasses)(*args, **kwargs) 
    129     return wrapper 
     241    return wraps(func)(wrapper) 
  • django/branches/queryset-refactor/django/views/decorators/cache.py

    r4265 r7173  
    1111account on caching -- just like the middleware does. 
    1212""" 
     13 
     14try: 
     15    from functools import wraps 
     16except ImportError: 
     17    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback. 
    1318 
    1419from django.utils.decorators import decorator_from_middleware 
     
    2732            return response 
    2833 
    29         return _cache_controlled 
     34        return wraps(viewfunc)(_cache_controlled) 
    3035 
    3136    return _cache_controller 
     
    4045        add_never_cache_headers(response) 
    4146        return response 
    42     return _wrapped_view_func 
     47    return wraps(view_func)(_wrapped_view_func) 
  • django/branches/queryset-refactor/django/views/decorators/http.py

    r4265 r7173  
    22Decorators for views based on HTTP headers. 
    33""" 
     4 
     5try: 
     6    from functools import wraps 
     7except ImportError: 
     8    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback. 
    49 
    510from django.utils.decorators import decorator_from_middleware 
     
    2530                return HttpResponseNotAllowed(request_method_list) 
    2631            return func(request, *args, **kwargs) 
    27         return inner 
     32        return wraps(func)(inner) 
    2833    return decorator 
    2934 
  • django/branches/queryset-refactor/django/views/decorators/vary.py

    r4265 r7173  
     1try: 
     2    from functools import wraps 
     3except ImportError: 
     4    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback. 
     5 
    16from django.utils.cache import patch_vary_headers 
    27 
     
    1722            patch_vary_headers(response, headers) 
    1823            return response 
    19         return inner_func 
     24        return wraps(func)(inner_func) 
    2025    return decorator 
    2126 
     
    3338        patch_vary_headers(response, ('Cookie',)) 
    3439        return response 
    35     return inner_func 
     40    return wraps(func)(inner_func) 
  • django/branches/queryset-refactor/docs/model-api.txt

    r7172 r7173  
    785785        # ... 
    786786 
    787 Note, however, that you can only use strings to refer to models in the same 
    788 models.py file -- you cannot use a string to reference a model in a different 
    789 application, or to reference a model that has been imported from elsewhere. 
     787Note, however, that this only refers to models in the same models.py file -- you 
     788cannot use a string to reference a model defined in another application or 
     789imported from elsewhere. 
     790 
     791**New in Django development version:** to refer to models defined in another 
     792application, you must instead explicitially specify the application label. That 
     793is, if the ``Manufacturer`` model above is defined in another application called 
     794``production``, you'd need to use:: 
     795 
     796    class Car(models.Model): 
     797        manufacturer = models.ForeignKey('production.Manufacturer') 
    790798 
    791799Behind the scenes, Django appends ``"_id"`` to the field name to create its 
  • django/branches/queryset-refactor/extras/django_bash_completion

    r5245 r7173  
    6262          # python manage.py, /some/path/python manage.py (if manage.py exists) 
    6363          ( ${COMP_CWORD} -eq 2 && 
    64             ( $( basename ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) && 
    65             ( $( basename ${COMP_WORDS[1]} ) == manage.py) && 
     64            ( $( basename -- ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) && 
     65            ( $( basename -- ${COMP_WORDS[1]} ) == manage.py) && 
    6666            ( -r ${COMP_WORDS[1]} ) )  
    6767          || 
    6868          ( ${COMP_CWORD} -eq 2 && 
    69             ( $( basename ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) && 
    70             ( $( basename ${COMP_WORDS[1]} ) == django-admin.py) && 
     69            ( $( basename -- ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) && 
     70            ( $( basename -- ${COMP_WORDS[1]} ) == django-admin.py) && 
    7171            ( -r ${COMP_WORDS[1]} ) ) ]] ; then 
    7272 
     
    150150    python_interpreters=$(whereis python | cut -d " " -f 2-)  
    151151    for python in $python_interpreters; do 
    152         pythons="${pythons} $(basename $python)" 
     152        pythons="${pythons} $(basename -- $python)" 
    153153    done 
    154154    pythons=$(echo $pythons | tr " " "\n" | sort -u | tr "\n" " ") 
  • django/branches/queryset-refactor/tests/modeltests/mutually_referential/models.py

    r5876 r7173  
    2224. Mutually referential many-to-one relationships 
    33 
    4 To define a many-to-one relationship, use ``ForeignKey()``
     4Strings can be used instead of model literals to set up "lazy" relations
    55""" 
    66 
     
    99class Parent(Model): 
    1010    name = CharField(max_length=100, core=True) 
     11     
     12    # Use a simple string for forward declarations. 
    1113    bestchild = ForeignKey("Child", null=True, related_name="favoured_by") 
    1214 
    1315class Child(Model): 
    1416    name = CharField(max_length=100) 
    15     parent = ForeignKey(Parent) 
     17     
     18    # You can also explicitally specify the related app. 
     19    parent = ForeignKey("mutually_referential.Parent") 
    1620 
    1721__test__ = {'API_TESTS':"""