Django

Code

Changeset 7853

Show
Ignore:
Timestamp:
07/06/08 10:23:24 (5 months ago)
Author:
brosner
Message:

newforms-admin: Merged from trunk up to [7852].

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/newforms-admin

    • Property svnmerge-integrated changed from /django/trunk:1-4345,4350-4357,4359-4365,4371-4372,4374-4377,4380-4386,4388,4390-4391,4400-4402,4404-4408,4410,4412-4419,4426-4427,4430-4432,4434,4441,4443-4444,4446-4447,4450,4452-4453,4455-4458,4476,4503,4546,4564-4569,4580-4586,4617,4630,4641-6390,6392-7829 to /django/trunk:1-4345,4350-4357,4359-4365,4371-4372,4374-4377,4380-4386,4388,4390-4391,4400-4402,4404-4408,4410,4412-4419,4426-4427,4430-4432,4434,4441,4443-4444,4446-4447,4450,4452-4453,4455-4458,4476,4503,4546,4564-4569,4580-4586,4617,4630,4641-6390,6392-7852
  • django/branches/newforms-admin/AUTHORS

    r7815 r7853  
    360360    Aaron Swartz <http://www.aaronsw.com/> 
    361361    Ville Säävuori <http://www.unessa.net/> 
     362    Christian Tanzer <tanzer@swing.co.at> 
    362363    Tyler Tarabula <tyler.tarabula@gmail.com> 
    363364    Tyson Tate <tyson@fallingbullets.com> 
  • django/branches/newforms-admin/django/bin/compile-messages.py

    r6777 r7853  
    11#!/usr/bin/env python 
    22 
    3 import optparse 
    4 import os 
    5 import sys 
     3if __name__ == "__main__": 
     4    import sys 
     5    name = sys.argv[0] 
     6    args = ' '.join(sys.argv[1:]) 
     7    print >> sys.stderr, "%s has been moved into django-admin.py" % name 
     8    print >> sys.stderr, 'Please run "django-admin.py compilemessages %s" instead.'% args 
     9    print >> sys.stderr 
     10    sys.exit(1) 
    611 
    7 try: 
    8     set 
    9 except NameError: 
    10     from sets import Set as set     # For Python 2.3 
    11  
    12  
    13 def compile_messages(locale=None): 
    14     basedirs = (os.path.join('conf', 'locale'), 'locale') 
    15     if os.environ.get('DJANGO_SETTINGS_MODULE'): 
    16         from django.conf import settings 
    17         basedirs += settings.LOCALE_PATHS 
    18  
    19     # Gather existing directories. 
    20     basedirs = set(map(os.path.abspath, filter(os.path.isdir, basedirs))) 
    21  
    22     if not basedirs: 
    23         print "This script should be run from the Django SVN tree or your project or app tree, or with the settings module specified." 
    24         sys.exit(1) 
    25  
    26     for basedir in basedirs: 
    27         if locale: 
    28             basedir = os.path.join(basedir, locale, 'LC_MESSAGES') 
    29         compile_messages_in_dir(basedir) 
    30  
    31 def compile_messages_in_dir(basedir): 
    32     for dirpath, dirnames, filenames in os.walk(basedir): 
    33         for f in filenames: 
    34             if f.endswith('.po'): 
    35                 sys.stderr.write('processing file %s in %s\n' % (f, dirpath)) 
    36                 pf = os.path.splitext(os.path.join(dirpath, f))[0] 
    37                 # Store the names of the .mo and .po files in an environment 
    38                 # variable, rather than doing a string replacement into the 
    39                 # command, so that we can take advantage of shell quoting, to 
    40                 # quote any malicious characters/escaping. 
    41                 # See http://cyberelk.net/tim/articles/cmdline/ar01s02.html 
    42                 os.environ['djangocompilemo'] = pf + '.mo' 
    43                 os.environ['djangocompilepo'] = pf + '.po' 
    44                 if sys.platform == 'win32': # Different shell-variable syntax 
    45                     cmd = 'msgfmt --check-format -o "%djangocompilemo%" "%djangocompilepo%"' 
    46                 else: 
    47                     cmd = 'msgfmt --check-format -o "$djangocompilemo" "$djangocompilepo"' 
    48                 os.system(cmd) 
    49  
    50 def main(): 
    51     parser = optparse.OptionParser() 
    52     parser.add_option('-l', '--locale', dest='locale', 
    53             help="The locale to process. Default is to process all.") 
    54     parser.add_option('--settings', 
    55         help='Python path to settings module, e.g. "myproject.settings". If provided, all LOCALE_PATHS will be processed. If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be checked as well.') 
    56     options, args = parser.parse_args() 
    57     if len(args): 
    58         parser.error("This program takes no arguments") 
    59     if options.settings: 
    60         os.environ['DJANGO_SETTINGS_MODULE'] = options.settings 
    61     compile_messages(options.locale) 
    62  
    63 if __name__ == "__main__": 
    64     main() 
  • django/branches/newforms-admin/django/bin/daily_cleanup.py

    r5440 r7853  
    88""" 
    99 
    10 import datetime 
    11 from django.db import transaction 
    12 from django.contrib.sessions.models import Session 
    13  
    14 def clean_up(): 
    15     """Clean up expired sessions.""" 
    16     Session.objects.filter(expire_date__lt=datetime.datetime.now()).delete() 
    17     transaction.commit_unless_managed() 
     10from django.core import management 
    1811 
    1912if __name__ == "__main__": 
    20     clean_up(
     13    management.call_command('cleanup'
  • django/branches/newforms-admin/django/bin/make-messages.py

    r7479 r7853  
    11#!/usr/bin/env python 
    22 
    3 # Need to ensure that the i18n framework is enabled 
    4 from django.conf import settings 
    5 settings.configure(USE_I18N = True) 
     3if __name__ == "__main__": 
     4    import sys 
     5    name = sys.argv[0] 
     6    args = ' '.join(sys.argv[1:]) 
     7    print >> sys.stderr, "%s has been moved into django-admin.py" % name 
     8    print >> sys.stderr, 'Please run "django-admin.py makemessages %s" instead.'% args 
     9    print >> sys.stderr 
     10    sys.exit(1) 
    611 
    7 from django.utils.translation import templatize 
    8 import re 
    9 import os 
    10 import sys 
    11 import getopt 
    12 from itertools import dropwhile 
    13  
    14 pythonize_re = re.compile(r'\n\s*//') 
    15  
    16 def make_messages(): 
    17     localedir = None 
    18  
    19     if os.path.isdir(os.path.join('conf', 'locale')): 
    20         localedir = os.path.abspath(os.path.join('conf', 'locale')) 
    21     elif os.path.isdir('locale'): 
    22         localedir = os.path.abspath('locale') 
    23     else: 
    24         print "This script should be run from the django svn tree or your project or app tree." 
    25         print "If you did indeed run it from the svn checkout or your project or application," 
    26         print "maybe you are just missing the conf/locale (in the django tree) or locale (for project" 
    27         print "and application) directory?" 
    28         print "make-messages.py doesn't create it automatically, you have to create it by hand if" 
    29         print "you want to enable i18n for your project or application." 
    30         sys.exit(1) 
    31  
    32     (opts, args) = getopt.getopt(sys.argv[1:], 'l:d:va') 
    33  
    34     lang = None 
    35     domain = 'django' 
    36     verbose = False 
    37     all = False 
    38  
    39     for o, v in opts: 
    40         if o == '-l': 
    41             lang = v 
    42         elif o == '-d': 
    43             domain = v 
    44         elif o == '-v': 
    45             verbose = True 
    46         elif o == '-a': 
    47             all = True 
    48  
    49     if domain not in ('django', 'djangojs'): 
    50         print "currently make-messages.py only supports domains 'django' and 'djangojs'" 
    51         sys.exit(1) 
    52     if (lang is None and not all) or domain is None: 
    53         print "usage: make-messages.py -l <language>" 
    54         print "   or: make-messages.py -a" 
    55         sys.exit(1) 
    56  
    57     languages = [] 
    58  
    59     if lang is not None: 
    60         languages.append(lang) 
    61     elif all: 
    62         languages = [el for el in os.listdir(localedir) if not el.startswith('.')] 
    63  
    64     for lang in languages: 
    65  
    66         print "processing language", lang 
    67         basedir = os.path.join(localedir, lang, 'LC_MESSAGES') 
    68         if not os.path.isdir(basedir): 
    69             os.makedirs(basedir) 
    70  
    71         pofile = os.path.join(basedir, '%s.po' % domain) 
    72         potfile = os.path.join(basedir, '%s.pot' % domain) 
    73  
    74         if os.path.exists(potfile): 
    75             os.unlink(potfile) 
    76  
    77         all_files = [] 
    78         for (dirpath, dirnames, filenames) in os.walk("."): 
    79             all_files.extend([(dirpath, f) for f in filenames]) 
    80         all_files.sort() 
    81         for dirpath, file in all_files: 
    82             if domain == 'djangojs' and file.endswith('.js'): 
    83                 if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) 
    84                 src = open(os.path.join(dirpath, file), "rb").read() 
    85                 src = pythonize_re.sub('\n#', src) 
    86                 open(os.path.join(dirpath, '%s.py' % file), "wb").write(src) 
    87                 thefile = '%s.py' % file 
    88                 cmd = 'xgettext -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (domain, os.path.join(dirpath, thefile)) 
    89                 (stdin, stdout, stderr) = os.popen3(cmd, 't') 
    90                 msgs = stdout.read() 
    91                 errors = stderr.read() 
    92                 if errors: 
    93                     print "errors happened while running xgettext on %s" % file 
    94                     print errors 
    95                     sys.exit(8) 
    96                 old = '#: '+os.path.join(dirpath, thefile)[2:] 
    97                 new = '#: '+os.path.join(dirpath, file)[2:] 
    98                 msgs = msgs.replace(old, new) 
    99                 if os.path.exists(potfile): 
    100                     # Strip the header 
    101                     msgs = '\n'.join(dropwhile(len, msgs.split('\n'))) 
    102                 else: 
    103                     msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8') 
    104                 if msgs: 
    105                     open(potfile, 'ab').write(msgs) 
    106                 os.unlink(os.path.join(dirpath, thefile)) 
    107             elif domain == 'django' and (file.endswith('.py') or file.endswith('.html')): 
    108                 thefile = file 
    109                 if file.endswith('.html'): 
    110                     src = open(os.path.join(dirpath, file), "rb").read() 
    111                     thefile = '%s.py' % file 
    112                     open(os.path.join(dirpath, thefile), "wb").write(templatize(src)) 
    113                 if verbose: 
    114                     sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) 
    115                 cmd = 'xgettext -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --keyword=ugettext_noop --keyword=ugettext_lazy --keyword=ungettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % ( 
    116                     domain, os.path.join(dirpath, thefile)) 
    117                 (stdin, stdout, stderr) = os.popen3(cmd, 't') 
    118                 msgs = stdout.read() 
    119                 errors = stderr.read() 
    120                 if errors: 
    121                     print "errors happened while running xgettext on %s" % file 
    122                     print errors 
    123                     sys.exit(8) 
    124                 if thefile != file: 
    125                     old = '#: '+os.path.join(dirpath, thefile)[2:] 
    126                     new = '#: '+os.path.join(dirpath, file)[2:] 
    127                     msgs = msgs.replace(old, new) 
    128                 if os.path.exists(potfile): 
    129                     # Strip the header 
    130                     msgs = '\n'.join(dropwhile(len, msgs.split('\n'))) 
    131                 else: 
    132                     msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8') 
    133                 if msgs: 
    134                     open(potfile, 'ab').write(msgs) 
    135                 if thefile != file: 
    136                     os.unlink(os.path.join(dirpath, thefile)) 
    137  
    138         if os.path.exists(potfile): 
    139             (stdin, stdout, stderr) = os.popen3('msguniq --to-code=utf-8 "%s"' % potfile, 'b') 
    140             msgs = stdout.read() 
    141             errors = stderr.read() 
    142             if errors: 
    143                 print "errors happened while running msguniq" 
    144                 print errors 
    145                 sys.exit(8) 
    146             open(potfile, 'w').write(msgs) 
    147             if os.path.exists(pofile): 
    148                 (stdin, stdout, stderr) = os.popen3('msgmerge -q "%s" "%s"' % (pofile, potfile), 'b') 
    149                 msgs = stdout.read() 
    150                 errors = stderr.read() 
    151                 if errors: 
    152                     print "errors happened while running msgmerge" 
    153                     print errors 
    154                     sys.exit(8) 
    155             open(pofile, 'wb').write(msgs) 
    156             os.unlink(potfile) 
    157  
    158 if __name__ == "__main__": 
    159     make_messages() 
  • django/branches/newforms-admin/django/conf/__init__.py

    r6955 r7853  
    7272        self._target = holder 
    7373 
     74    def configured(self): 
     75        """ 
     76        Returns True if the settings have already been configured. 
     77        """ 
     78        return bool(self._target) 
     79    configured = property(configured) 
     80 
    7481class Settings(object): 
    7582    def __init__(self, settings_module): 
  • django/branches/newforms-admin/django/core/context_processors.py

    r6371 r7853  
    3939 
    4040def i18n(request): 
     41    from django.utils import translation 
     42 
    4143    context_extras = {} 
    4244    context_extras['LANGUAGES'] = settings.LANGUAGES 
    43     if hasattr(request, 'LANGUAGE_CODE'): 
    44         context_extras['LANGUAGE_CODE'] = request.LANGUAGE_CODE 
    45     else: 
    46         context_extras['LANGUAGE_CODE'] = settings.LANGUAGE_CODE 
    47  
    48     from django.utils import translation 
     45    context_extras['LANGUAGE_CODE'] = translation.get_language() 
    4946    context_extras['LANGUAGE_BIDI'] = translation.get_language_bidi() 
    5047 
  • django/branches/newforms-admin/django/core/management/base.py

    r7351 r7853  
    66from django.core.exceptions import ImproperlyConfigured 
    77from django.core.management.color import color_style 
     8 
     9try: 
     10    set 
     11except NameError: 
     12    from sets import Set as set     # For Python 2.3 
    813 
    914class CommandError(Exception): 
  • django/branches/newforms-admin/django/core/validators.py

    r7351 r7853  
    178178    from cStringIO import StringIO 
    179179    try: 
    180         content = field_data['content'] 
     180        content = field_data.read() 
    181181    except TypeError: 
    182182        raise ValidationError, _("No file was submitted. Check the encoding type on the form.") 
     
    470470    def __call__(self, field_data, all_data): 
    471471        try: 
    472             content = field_data['content'] 
     472            content = field_data.read() 
    473473        except TypeError: 
    474474            raise ValidationError, ugettext_lazy("No file was submitted. Check the encoding type on the form.") 
  • django/branches/newforms-admin/django/db/backends/__init__.py

    r7809 r7853  
    162162        return cursor.lastrowid 
    163163 
    164     def limit_offset_sql(self, limit, offset=None): 
    165         """ 
    166         Returns a LIMIT/OFFSET SQL clause, given a limit and optional offset. 
    167         """ 
    168         # 'LIMIT 40 OFFSET 20' 
    169         sql = "LIMIT %s" % limit 
    170         if offset and offset != 0: 
    171             sql += " OFFSET %s" % offset 
    172         return sql 
    173  
    174164    def lookup_cast(self, lookup_type): 
    175165        """ 
  • django/branches/newforms-admin/django/db/backends/mysql/base.py

    r7809 r7853  
    8989    def fulltext_search_sql(self, field_name): 
    9090        return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name 
    91  
    92     def limit_offset_sql(self, limit, offset=None): 
    93         # 'LIMIT 20,40' 
    94         sql = "LIMIT " 
    95         if offset and offset != 0: 
    96             sql += "%s," % offset 
    97         return sql + str(limit) 
    9891 
    9992    def no_limit_value(self): 
  • django/branches/newforms-admin/django/db/backends/mysql_old/base.py

    r7809 r7853  
    9393    def fulltext_search_sql(self, field_name): 
    9494        return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name 
    95  
    96     def limit_offset_sql(self, limit, offset=None): 
    97         # 'LIMIT 20,40' 
    98         sql = "LIMIT " 
    99         if offset and offset != 0: 
    100             sql += "%s," % offset 
    101         return sql + str(limit) 
    10295 
    10396    def no_limit_value(self): 
  • django/branches/newforms-admin/django/db/backends/oracle/base.py

    r7809 r7853  
    8888        return cursor.fetchone()[0] 
    8989 
    90     def limit_offset_sql(self, limit, offset=None): 
    91         # Limits and offset are too complicated to be handled here. 
    92         # Instead, they are handled in django/db/backends/oracle/query.py. 
    93         return "" 
    94  
    9590    def lookup_cast(self, lookup_type): 
    9691        if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith'): 
     
    147142            # ALTER code will reset the sequence to 0. 
    148143            for sequence_info in sequences: 
    149                 table_name = sequence_info['table'] 
    150                 seq_name = get_sequence_name(table_name
     144                sequence_name = get_sequence_name(sequence_info['table']) 
     145                table_name = self.quote_name(sequence_info['table']
    151146                column_name = self.quote_name(sequence_info['column'] or 'id') 
    152                 query = _get_sequence_reset_sql() % {'sequence': seq_name, 
    153                                                      'table': self.quote_name(table_name)
     147                query = _get_sequence_reset_sql() % {'sequence': sequence_name, 
     148                                                     'table': table_name
    154149                                                     'column': column_name} 
    155150                sql.append(query) 
     
    163158        query = _get_sequence_reset_sql() 
    164159        for model in model_list: 
    165             for f in model._meta.fields: 
     160            for f in model._meta.local_fields: 
    166161                if isinstance(f, models.AutoField): 
     162                    table_name = self.quote_name(model._meta.db_table) 
    167163                    sequence_name = get_sequence_name(model._meta.db_table) 
    168                     column_name = self.quote_name(f.db_column or f.name
     164                    column_name = self.quote_name(f.column
    169165                    output.append(query % {'sequence': sequence_name, 
    170                                            'table': model._meta.db_table, 
     166                                           'table': table_name, 
    171167                                           'column': column_name}) 
    172168                    break # Only one AutoField is allowed per model, so don't bother continuing. 
    173169            for f in model._meta.many_to_many: 
     170                table_name = self.quote_name(f.m2m_db_table()) 
    174171                sequence_name = get_sequence_name(f.m2m_db_table()) 
     172                column_name = self.quote_name('id') 
    175173                output.append(query % {'sequence': sequence_name, 
    176                                        'table': f.m2m_db_table()
    177                                        'column': self.quote_name('id')}) 
     174                                       'table': table_name
     175                                       'column': column_name}) 
    178176        return output 
    179177 
  • django/branches/newforms-admin/django/db/models/base.py

    r7815 r7853  
    3232    "Metaclass for all models" 
    3333    def __new__(cls, name, bases, attrs): 
    34         # If this isn't a subclass of Model, don't do anything special. 
    35         try: 
    36             parents = [b for b in bases if issubclass(b, Model)] 
    37         except NameError: 
    38             # 'Model' isn't defined yet, meaning we're looking at Django's own 
    39             # Model class, defined below. 
    40             parents = [] 
     34        super_new = super(ModelBase, cls).__new__ 
     35        parents = [b for b in bases if isinstance(b, ModelBase)] 
    4136        if not parents: 
    42             return super(ModelBase, cls).__new__(cls, name, bases, attrs) 
     37            # If this isn't a subclass of Model, don't do anything special. 
     38            return super_new(cls, name, bases, attrs) 
    4339 
    4440        # Create the class. 
    4541        module = attrs.pop('__module__') 
    46         new_class = type.__new__(cls, name, bases, {'__module__': module}) 
     42        new_class = super_new(cls, name, bases, {'__module__': module}) 
    4743        attr_meta = attrs.pop('Meta', None) 
    4844        abstract = getattr(attr_meta, 'abstract', False) 
  • django/branches/newforms-admin/django/db/models/sql/query.py

    r7815 r7853  
    11051105                self.promote_alias(table) 
    11061106 
    1107         # To save memory and copying time, convert the value from the Python 
    1108         # object to the actual value used in the SQL query. 
    1109         if field: 
    1110             params = field.get_db_prep_lookup(lookup_type, value) 
    1111         else: 
    1112             params = Field().get_db_prep_lookup(lookup_type, value) 
    1113         if isinstance(value, datetime.datetime): 
    1114             annotation = datetime.datetime 
    1115         else: 
    1116             annotation = bool(value) 
    1117  
    1118         self.where.add((alias, col, field.db_type(), lookup_type, annotation, 
    1119             params), connector) 
     1107        self.where.add((alias, col, field, lookup_type, value), connector) 
    11201108 
    11211109        if negate: 
     
    11271115                        if self.alias_map[alias][JOIN_TYPE] == self.LOUTER: 
    11281116                            j_col = self.alias_map[alias][RHS_JOIN_COL] 
    1129                             entry = Node([(alias, j_col, None, 'isnull', True, 
    1130                                     [True])]
     1117                            entry = self.where_class() 
     1118                            entry.add((alias, j_col, None, 'isnull', True), AND
    11311119                            entry.negate() 
    11321120                            self.where.add(entry, AND) 
     
    11361124                    # exclude the "foo__in=[]" case from this handling, because 
    11371125                    # it's short-circuited in the Where class. 
    1138                     entry = Node([(alias, col, None, 'isnull', True, [True])]) 
     1126                    entry = self.where_class() 
     1127                    entry.add((alias, col, None, 'isnull', True), AND) 
    11391128                    entry.negate() 
    11401129                    self.where.add(entry, AND) 
  • django/branches/newforms-admin/django/db/models/sql/subqueries.py

    r7809 r7853  
    5050                    where = self.where_class() 
    5151                    where.add((None, related.field.m2m_reverse_name(), 
    52                             related.field.db_type(), 'in', True
     52                            related.field, 'in'
    5353                            pk_list[offset : offset+GET_ITERATOR_CHUNK_SIZE]), 
    5454                            AND) 
     
    6060                from django.contrib.contenttypes.models import ContentType 
    6161                field = f.rel.to._meta.get_field(f.content_type_field_name) 
    62                 w1.add((None, field.column, field.db_type(), 'exact', True
    63                         [ContentType.objects.get_for_model(cls).id]), AND) 
     62                w1.add((None, field.column, field, 'exact'
     63                        ContentType.objects.get_for_model(cls).id), AND) 
    6464            for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): 
    6565                where = self.where_class() 
    66                 where.add((None, f.m2m_column_name(), f.db_type(), 'in', True
     66                where.add((None, f.m2m_column_name(), f, 'in'
    6767                        pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]), 
    6868                        AND) 
     
    8282            where = self.where_class() 
    8383            field = self.model._meta.pk 
    84             where.add((None, field.column, field.db_type(), 'in', True
     84            where.add((None, field.column, field, 'in'
    8585                    pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]), AND) 
    8686            self.do_query(self.model._meta.db_table, where) 
     
    205205            self.where = self.where_class() 
    206206            f = self.model._meta.pk 
    207             self.where.add((None, f.column, f.db_type(), 'in', True
     207            self.where.add((None, f.column, f, 'in'
    208208                    pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]), 
    209209                    AND) 
  • django/branches/newforms-admin/django/db/models/sql/where.py

    r7809 r7853  
    2828    default = AND 
    2929 
    30     def as_sql(self, node=None, qn=None): 
     30    def add(self, data, connector): 
     31        """ 
     32        Add a node to the where-tree. If the data is a list or tuple, it is 
     33        expected to be of the form (alias, col_name, field_obj, lookup_type, 
     34        value), which is then slightly munged before being stored (to avoid 
     35        storing any reference to field objects). Otherwise, the 'data' is 
     36        stored unchanged and can be anything with an 'as_sql()' method. 
     37        """ 
     38        if not isinstance(data, (list, tuple)): 
     39            super(WhereNode, self).add(data, connector) 
     40            return 
     41 
     42        alias, col, field, lookup_type, value = data 
     43        if field: 
     44            params = field.get_db_prep_lookup(lookup_type, value) 
     45            db_type = field.db_type() 
     46        else: 
     47            # This is possible when we add a comparison to NULL sometimes (we 
     48            # don't really need to waste time looking up the associated field 
     49            # object). 
     50            params = Field().get_db_prep_lookup(lookup_type, value) 
     51            db_type = None 
     52        if isinstance(value, datetime.datetime): 
     53            annotation = datetime.datetime 
     54        else: 
     55            annotation = bool(value) 
     56        super(WhereNode, self).add((alias, col, db_type, lookup_type, 
     57                annotation, params), connector) 
     58 
     59    def as_sql(self, qn=None): 
    3160        """ 
    3261        Returns the SQL version of the where clause and the value to be 
     
    3766        recursion). 
    3867        """ 
    39         if node is None: 
    40             node = self 
    4168        if not qn: 
    4269            qn = connection.ops.quote_name 
    43         if not node.children: 
     70        if not self.children: 
    4471            return None, [] 
    4572        result = [] 
    4673        result_params = [] 
    4774        empty = True 
    48         for child in node.children: 
     75        for child in self.children: 
    4976            try: 
    5077                if hasattr(child, 'as_sql'): 
    5178                    sql, params = child.as_sql(qn=qn) 
    52                     format = '(%s)' 
    53                 elif isinstance(child, tree.Node): 
    54                     sql, params = self.as_sql(child, qn) 
    55                     if child.negated: 
    56                         format = 'NOT (%s)' 
    57                     elif len(child.children) == 1: 
    58                         format = '%s' 
    59                     else: 
    60                         format = '(%s)' 
    6179                else: 
     80                    # A leaf node in the tree. 
    6281                    sql, params = self.make_atom(child, qn) 
    63                     format = '%s' 
    6482            except EmptyResultSet: 
    65                 if node.connector == AND and not node.negated: 
     83                if self.connector == AND and not self.negated: 
    6684                    # We can bail out early in this particular case (only). 
    6785                    raise 
    68                 elif node.negated: 
     86                elif self.negated: 
    6987                    empty = False 
    7088                continue 
    7189            except FullResultSet: 
    7290                if self.connector == OR: 
    73                     if node.negated: 
     91                    if self.negated: 
    7492                        empty = True 
    7593                        break 
    7694                    # We match everything. No need for any constraints. 
    7795                    return '', [] 
    78                 if node.negated: 
     96                if self.negated: 
    7997                    empty = True 
    8098                continue 
    8199            empty = False 
    82100            if sql: 
    83                 result.append(format % sql) 
     101                result.append(sql) 
    84102                result_params.extend(params) 
    85103        if empty: 
    86104            raise EmptyResultSet 
    87         conn = ' %s ' % node.connector 
    88         return conn.join(result), result_params 
     105 
     106        conn = ' %s ' % self.connector 
     107        sql_string = conn.join(result) 
     108        if sql_string: 
     109            if self.negated: 
     110                sql_string = 'NOT (%s)' % sql_string 
     111            elif len(self.children) != 1: 
     112                sql_string = '(%s)' % sql_string 
     113        return sql_string, result_params 
    89114 
    90115    def make_atom(self, child, qn): 
    91116        """ 
    92         Turn a tuple (table_alias, field_name, db_type, lookup_type, 
     117        Turn a tuple (table_alias, column_name, db_type, lookup_type, 
    93118        value_annot, params) into valid SQL. 
    94119 
  • django/branches/newforms-admin/django/newforms/forms.py

    r7507 r7853  
    5858    def __new__(cls, name, bases, attrs): 
    5959        attrs['base_fields'] = get_declared_fields(bases, attrs) 
    60  
    61         new_class = type.__new__(cls, name, bases, attrs) 
     60        new_class = super(DeclarativeFieldsMetaclass, 
     61                     cls).__new__(cls, name, bases, attrs) 
    6262        if 'media' not in attrs: 
    6363            new_class.media = media_property(new_class) 
  • django/branches/newforms-admin/django/newforms/models.py

    r7730 r7853  
    216216 
    217217class ModelFormMetaclass(type): 
    218     def __new__(cls, name, bases, attrs, 
    219                 formfield_callback=lambda f: f.formfield()): 
     218    def __new__(cls, name, bases, attrs): 
     219        formfield_callback = attrs.pop('formfield_callback', 
     220                lambda f: f.formfield()) 
    220221        try: 
    221222            parents = [b for b in bases if issubclass(b, ModelForm)] 
     
    223224            # We are defining ModelForm itself. 
    224225            parents = None 
     226        new_class = super(ModelFormMetaclass, cls).__new__(cls, name, bases, 
     227                attrs) 
    225228        if not parents: 
    226             return super(ModelFormMetaclass, cls).__new__(cls, name, bases, 
    227                     attrs) 
    228  
    229         new_class = type.__new__(cls, name, bases, attrs) 
     229            return new_class 
     230 
    230231        if 'media' not in attrs: 
    231232            new_class.media = media_property(new_class) 
  • django/branches/newforms-admin/django/utils/tree.py

    r7479 r7853  
    2929        self.subtree_parents = [] 
    3030        self.negated = negated 
     31 
     32    # We need this because of django.db.models.query_utils.Q. Q. __init__() is 
     33    # problematic, but it is a natural Node subclass in all other respects. 
     34    def _new_instance(cls, children=None, connector=None, negated=False): 
     35        """ 
     36        This is called to create a new instance of this class when we need new 
     37        Nodes (or subclasses) in the internal code in this class. Normally, it 
     38        just shadows __init__(). However, subclasses with an __init__ signature 
     39        that is not an extension of Node.__init__ might need to implement this 
     40&n