~ubuntu-branches/ubuntu/quantal/python-django/quantal-security

« back to all changes in this revision

Viewing changes to django/db/models/fields/subclassing.py

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2010-05-21 07:52:55 UTC
  • mfrom: (1.3.6 upstream)
  • mto: This revision was merged to the branch mainline in revision 28.
  • Revision ID: james.westby@ubuntu.com-20100521075255-ii78v1dyfmyu3uzx
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
"""
2
 
Convenience routines for creating non-trivial Field subclasses.
 
2
Convenience routines for creating non-trivial Field subclasses, as well as
 
3
backwards compatibility utilities.
3
4
 
4
5
Add SubfieldBase as the __metaclass__ for your Field subclass, implement
5
6
to_python() and the other necessary methods and everything will work seamlessly.
6
7
"""
7
8
 
8
 
class SubfieldBase(type):
 
9
from inspect import getargspec
 
10
from warnings import warn
 
11
 
 
12
def call_with_connection(func):
 
13
    arg_names, varargs, varkwargs, defaults = getargspec(func)
 
14
    updated = ('connection' in arg_names or varkwargs)
 
15
    if not updated:
 
16
        warn("A Field class whose %s method hasn't been updated to take a "
 
17
            "`connection` argument." % func.__name__,
 
18
            PendingDeprecationWarning, stacklevel=2)
 
19
 
 
20
    def inner(*args, **kwargs):
 
21
        if 'connection' not in kwargs:
 
22
            from django.db import connection
 
23
            kwargs['connection'] = connection
 
24
            warn("%s has been called without providing a connection argument. " %
 
25
                func.__name__, PendingDeprecationWarning,
 
26
                stacklevel=1)
 
27
        if updated:
 
28
            return func(*args, **kwargs)
 
29
        if 'connection' in kwargs:
 
30
            del kwargs['connection']
 
31
        return func(*args, **kwargs)
 
32
    return inner
 
33
 
 
34
def call_with_connection_and_prepared(func):
 
35
    arg_names, varargs, varkwargs, defaults = getargspec(func)
 
36
    updated = (
 
37
        ('connection' in arg_names or varkwargs) and
 
38
        ('prepared' in arg_names or varkwargs)
 
39
    )
 
40
    if not updated:
 
41
        warn("A Field class whose %s method hasn't been updated to take "
 
42
            "`connection` and `prepared` arguments." % func.__name__,
 
43
            PendingDeprecationWarning, stacklevel=2)
 
44
 
 
45
    def inner(*args, **kwargs):
 
46
        if 'connection' not in kwargs:
 
47
            from django.db import connection
 
48
            kwargs['connection'] = connection
 
49
            warn("%s has been called without providing a connection argument. " %
 
50
                func.__name__, PendingDeprecationWarning,
 
51
                stacklevel=1)
 
52
        if updated:
 
53
            return func(*args, **kwargs)
 
54
        if 'connection' in kwargs:
 
55
            del kwargs['connection']
 
56
        if 'prepared' in kwargs:
 
57
            del kwargs['prepared']
 
58
        return func(*args, **kwargs)
 
59
    return inner
 
60
 
 
61
class LegacyConnection(type):
 
62
    """
 
63
    A metaclass to normalize arguments give to the get_db_prep_* and db_type
 
64
    methods on fields.
 
65
    """
 
66
    def __new__(cls, names, bases, attrs):
 
67
        new_cls = super(LegacyConnection, cls).__new__(cls, names, bases, attrs)
 
68
        for attr in ('db_type', 'get_db_prep_save'):
 
69
            setattr(new_cls, attr, call_with_connection(getattr(new_cls, attr)))
 
70
        for attr in ('get_db_prep_lookup', 'get_db_prep_value'):
 
71
            setattr(new_cls, attr, call_with_connection_and_prepared(getattr(new_cls, attr)))
 
72
        return new_cls
 
73
 
 
74
class SubfieldBase(LegacyConnection):
9
75
    """
10
76
    A metaclass for custom Field subclasses. This ensures the model's attribute
11
77
    has the descriptor protocol attached to it.
26
92
    def __get__(self, obj, type=None):
27
93
        if obj is None:
28
94
            raise AttributeError('Can only be accessed via an instance.')
29
 
        return obj.__dict__[self.field.name]        
 
95
        return obj.__dict__[self.field.name]
30
96
 
31
97
    def __set__(self, obj, value):
32
98
        obj.__dict__[self.field.name] = self.field.to_python(value)