Ticket #87: __init__.2.py

File __init__.2.py, 77.0 KB (added by Jason Huggins, 15 years ago)

django\core\meta\init.py

Line 
1from django.conf import settings
2from django.core import formfields, validators
3from django.core import db
4from django.core.exceptions import ObjectDoesNotExist
5from django.core.meta.fields import *
6from django.utils.functional import curry
7from django.utils.text import capfirst
8import copy, datetime, os, re, sys, types
9
10# Admin stages.
11ADD, CHANGE, BOTH = 1, 2, 3
12
13# Size of each "chunk" for get_iterator calls.
14# Larger values are slightly faster at the expense of more storage space.
15GET_ITERATOR_CHUNK_SIZE = 100
16
17# Prefix (in Python path style) to location of models.
18MODEL_PREFIX = 'django.models'
19
20# Methods on models with the following prefix will be removed and
21# converted to module-level functions.
22MODEL_FUNCTIONS_PREFIX = '_module_'
23
24# Methods on models with the following prefix will be removed and
25# converted to manipulator methods.
26MANIPULATOR_FUNCTIONS_PREFIX = '_manipulator_'
27
28LOOKUP_SEPARATOR = '__'
29
30####################
31# HELPER FUNCTIONS #
32####################
33
34# Django currently supports two forms of ordering.
35# Form 1 (deprecated) example:
36#     order_by=(('pub_date', 'DESC'), ('headline', 'ASC'), (None, 'RANDOM'))
37# Form 2 (new-style) example:
38#     order_by=('-pub_date', 'headline', '?')
39# Form 1 is deprecated and will no longer be supported for Django's first
40# official release. The following code converts from Form 1 to Form 2.
41
42LEGACY_ORDERING_MAPPING = {'ASC': '_', 'DESC': '-_', 'RANDOM': '?'}
43
44def handle_legacy_orderlist(order_list):
45    if not order_list or isinstance(order_list[0], basestring):
46        return order_list
47    else:
48        import warnings
49        new_order_list = [LEGACY_ORDERING_MAPPING[j.upper()].replace('_', str(i)) for i, j in order_list]
50        warnings.warn("%r ordering syntax is deprecated. Use %r instead." % (order_list, new_order_list), DeprecationWarning)
51        return new_order_list
52
53def orderlist2sql(order_list, prefix=''):
54    output = []
55    for f in handle_legacy_orderlist(order_list):
56        if f.startswith('-'):
57            output.append('%s%s DESC' % (prefix, f[1:]))
58        elif f == '?':
59            output.append('RANDOM()')
60        else:
61            output.append('%s%s ASC' % (prefix, f))
62    return ', '.join(output)
63
64def get_module(app_label, module_name):
65    return __import__('%s.%s.%s' % (MODEL_PREFIX, app_label, module_name), '', '', [''])
66
67def get_app(app_label):
68    return __import__('%s.%s' % (MODEL_PREFIX, app_label), '', '', [''])
69
70_installed_models_cache = None
71def get_installed_models():
72    """
73    Returns a list of installed "models" packages, such as foo.models,
74    ellington.news.models, etc. This does NOT include django.models.
75    """
76    global _installed_models_cache
77    if _installed_models_cache is not None:
78        return _installed_models_cache
79    _installed_models_cache = []
80    for a in settings.INSTALLED_APPS:
81        try:
82            _installed_models_cache.append(__import__(a + '.models', '', '', ['']))
83        except ImportError:
84            pass
85    return _installed_models_cache
86
87_installed_modules_cache = None
88def get_installed_model_modules(core_models=None):
89    """
90    Returns a list of installed models, such as django.models.core,
91    ellington.news.models.news, foo.models.bar, etc.
92    """
93    global _installed_modules_cache
94    if _installed_modules_cache is not None:
95        return _installed_modules_cache
96    _installed_modules_cache = []
97
98    # django.models is a special case.
99    for submodule in (core_models or []):
100        _installed_modules_cache.append(__import__('django.models.%s' % submodule, '', '', ['']))
101    for m in get_installed_models():
102        for submodule in getattr(m, '__all__', []):
103            mod = __import__('django.models.%s' % submodule, '', '', [''])
104            try:
105                mod._MODELS
106            except AttributeError:
107                pass # Skip model modules that don't actually have models in them.
108            else:
109                _installed_modules_cache.append(mod)
110    return _installed_modules_cache
111
112class LazyDate:
113    """
114    Use in limit_choices_to to compare the field to dates calculated at run time
115    instead of when the model is loaded.  For example::
116
117        ... limit_choices_to = {'date__gt' : meta.LazyDate(days=-3)} ...
118
119    which will limit the choices to dates greater than three days ago.
120    """
121    def __init__(self, **kwargs):
122        self.delta = datetime.timedelta(**kwargs)
123
124    def __str__(self):
125        return str(self.__get_value__())
126
127    def __repr__(self):
128        return "<LazyDate: %s>" % self.delta
129
130    def __get_value__(self):
131        return datetime.datetime.now() + self.delta
132
133################
134# MAIN CLASSES #
135################
136
137class FieldDoesNotExist(Exception):
138    pass
139
140class BadKeywordArguments(Exception):
141    pass
142
143class Options:
144    def __init__(self, module_name='', verbose_name='', verbose_name_plural='', db_table='',
145        fields=None, ordering=None, unique_together=None, admin=None, has_related_links=False,
146        where_constraints=None, object_name=None, app_label=None,
147        exceptions=None, permissions=None, get_latest_by=None,
148        order_with_respect_to=None, module_constants=None):
149
150        # Save the original function args, for use by copy(). Note that we're
151        # NOT using copy.deepcopy(), because that would create a new copy of
152        # everything in memory, and it's better to conserve memory. Of course,
153        # this comes with the important gotcha that changing any attribute of
154        # this object will change its value in self._orig_init_args, so we
155        # need to be careful not to do that. In practice, we can pull this off
156        # because Options are generally read-only objects, and __init__() is
157        # the only place where its attributes are manipulated.
158
159        # locals() is used purely for convenience, so we don't have to do
160        # something verbose like this:
161        #    self._orig_init_args = {
162        #       'module_name': module_name,
163        #       'verbose_name': verbose_name,
164        #       ...
165        #    }
166        self._orig_init_args = locals()
167        del self._orig_init_args['self'] # because we don't care about it.
168
169        # Move many-to-many related fields from self.fields into self.many_to_many.
170        self.fields, self.many_to_many = [], []
171        for field in (fields or []):
172            if field.rel and isinstance(field.rel, ManyToMany):
173                self.many_to_many.append(field)
174            else:
175                self.fields.append(field)
176        self.module_name, self.verbose_name = module_name, verbose_name
177        self.verbose_name_plural = verbose_name_plural or verbose_name + 's'
178        self.db_table, self.has_related_links = db_table, has_related_links
179        self.ordering = ordering or []
180        self.unique_together = unique_together or []
181        self.where_constraints = where_constraints or []
182        self.exceptions = exceptions or []
183        self.permissions = permissions or []
184        self.object_name, self.app_label = object_name, app_label
185        self.get_latest_by = get_latest_by
186        if order_with_respect_to:
187            self.order_with_respect_to = self.get_field(order_with_respect_to)
188            self.ordering = ('_order',)
189        else:
190            self.order_with_respect_to = None
191        self.module_constants = module_constants or {}
192        self.admin = admin
193
194        # Calculate one_to_one_field.
195        self.one_to_one_field = None
196        for f in self.fields:
197            if isinstance(f.rel, OneToOne):
198                self.one_to_one_field = f
199                break
200        # Cache the primary-key field.
201        self.pk = None
202        for f in self.fields:
203            if f.primary_key:
204                self.pk = f
205                break
206        # If a primary_key field hasn't been specified, add an
207        # auto-incrementing primary-key ID field automatically.
208        if self.pk is None:
209            self.fields.insert(0, AutoField('id', 'ID', primary_key=True))
210            self.pk = self.fields[0]
211        # Cache whether this has an AutoField.
212        self.has_auto_field = False
213        for f in self.fields:
214            is_auto = isinstance(f, AutoField)
215            if is_auto and self.has_auto_field:
216                raise AssertionError, "A model can't have more than one AutoField."
217            elif is_auto:
218                self.has_auto_field = True
219
220    def __repr__(self):
221        return '<Options for %s>' % self.module_name
222
223    def copy(self, **kwargs):
224        args = self._orig_init_args.copy()
225        args.update(kwargs)
226        return self.__class__(**args)
227
228    def get_model_module(self):
229        return get_module(self.app_label, self.module_name)
230
231    def get_content_type_id(self):
232        "Returns the content-type ID for this object type."
233        if not hasattr(self, '_content_type_id'):
234            mod = get_module('core', 'contenttypes')
235            self._content_type_id = mod.get_object(python_module_name__exact=self.module_name, package__label__exact=self.app_label).id
236        return self._content_type_id
237
238    def get_field(self, name, many_to_many=True):
239        """
240        Returns the requested field by name. Raises FieldDoesNotExist on error.
241        """
242        to_search = many_to_many and (self.fields + self.many_to_many) or self.fields
243        for f in to_search:
244            if f.name == name:
245                return f
246        raise FieldDoesNotExist, "name=%s" % name
247
248    def get_order_sql(self, table_prefix=''):
249        "Returns the full 'ORDER BY' clause for this object, according to self.ordering."
250        if not self.ordering: return ''
251        pre = table_prefix and (table_prefix + '.') or ''
252        return 'ORDER BY ' + orderlist2sql(self.ordering, pre)
253
254    def get_add_permission(self):
255        return 'add_%s' % self.object_name.lower()
256
257    def get_change_permission(self):
258        return 'change_%s' % self.object_name.lower()
259
260    def get_delete_permission(self):
261        return 'delete_%s' % self.object_name.lower()
262
263    def get_rel_object_method_name(self, rel_opts, rel_field):
264        # This method encapsulates the logic that decides what name to give a
265        # method that retrieves related many-to-one objects. Usually it just
266        # uses the lower-cased object_name, but if the related object is in
267        # another app, its app_label is appended.
268        #
269        # Examples:
270        #
271        #   # Normal case -- a related object in the same app.
272        #   # This method returns "choice".
273        #   Poll.get_choice_list()
274        #
275        #   # A related object in a different app.
276        #   # This method returns "lcom_bestofaward".
277        #   Place.get_lcom_bestofaward_list() # "lcom_bestofaward"
278        rel_obj_name = rel_field.rel.related_name or rel_opts.object_name.lower()
279        if self.app_label != rel_opts.app_label:
280            rel_obj_name = '%s_%s' % (rel_opts.app_label, rel_obj_name)
281        return rel_obj_name
282
283    def get_all_related_objects(self):
284        try: # Try the cache first.
285            return self._all_related_objects
286        except AttributeError:
287            module_list = get_installed_model_modules()
288            rel_objs = []
289            for mod in module_list:
290                for klass in mod._MODELS:
291                    for f in klass._meta.fields:
292                        if f.rel and self == f.rel.to:
293                            rel_objs.append((klass._meta, f))
294            if self.has_related_links:
295                # Manually add RelatedLink objects, which are a special case.
296                core = get_module('relatedlinks', 'relatedlinks')
297                # Note that the copy() is very important -- otherwise any
298                # subsequently loaded object with related links will override this
299                # relationship we're adding.
300                link_field = copy.copy(core.RelatedLink._meta.get_field('object_id'))
301                link_field.rel = ManyToOne(self.get_model_module().Klass, 'related_links', 'id',
302                    num_in_admin=3, min_num_in_admin=3, edit_inline=TABULAR,
303                    lookup_overrides={
304                        'content_type__package__label__exact': self.app_label,
305                        'content_type__python_module_name__exact': self.module_name
306                    })
307                rel_objs.append((core.RelatedLink._meta, link_field))
308            self._all_related_objects = rel_objs
309            return rel_objs
310
311    def get_inline_related_objects(self):
312        return [(a, b) for a, b in self.get_all_related_objects() if b.rel.edit_inline]
313
314    def get_all_related_many_to_many_objects(self):
315        module_list = get_installed_model_modules()
316        rel_objs = []
317        for mod in module_list:
318            for klass in mod._MODELS:
319                try:
320                    for f in klass._meta.many_to_many:
321                        if f.rel and self == f.rel.to:
322                            rel_objs.append((klass._meta, f))
323                            raise StopIteration
324                except StopIteration:
325                    continue
326        return rel_objs
327
328    def get_ordered_objects(self):
329        "Returns a list of Options objects that are ordered with respect to this object."
330        if not hasattr(self, '_ordered_objects'):
331            objects = []
332            for klass in get_app(self.app_label)._MODELS:
333                opts = klass._meta
334                if opts.order_with_respect_to and opts.order_with_respect_to.rel \
335                    and self == opts.order_with_respect_to.rel.to:
336                    objects.append(opts)
337            self._ordered_objects = objects
338        return self._ordered_objects
339
340    def has_field_type(self, field_type):
341        """
342        Returns True if this object's admin form has at least one of the given
343        field_type (e.g. FileField).
344        """
345        if not hasattr(self, '_field_types'):
346            self._field_types = {}
347        if not self._field_types.has_key(field_type):
348            try:
349                # First check self.fields.
350                for f in self.fields:
351                    if isinstance(f, field_type):
352                        raise StopIteration
353                # Failing that, check related fields.
354                for rel_obj, rel_field in self.get_inline_related_objects():
355                    for f in rel_obj.fields:
356                        if isinstance(f, field_type):
357                            raise StopIteration
358            except StopIteration:
359                self._field_types[field_type] = True
360            else:
361                self._field_types[field_type] = False
362        return self._field_types[field_type]
363
364def _reassign_globals(function_dict, extra_globals, namespace):
365    new_functions = {}
366    for k, v in function_dict.items():
367        # Get the code object.
368        code = v.func_code
369        # Recreate the function, but give it access to extra_globals and the
370        # given namespace's globals, too.
371        new_globals = {'__builtins__': __builtins__, 'db': db.db, 'datetime': datetime}
372        new_globals.update(extra_globals.__dict__)
373        func = types.FunctionType(code, globals=new_globals, name=k, argdefs=v.func_defaults)
374        func.__dict__.update(v.__dict__)
375        setattr(namespace, k, func)
376        # For all of the custom functions that have been added so far, give
377        # them access to the new function we've just created.
378        for new_k, new_v in new_functions.items():
379            new_v.func_globals[k] = func
380        new_functions[k] = func
381
382class ModelBase(type):
383    "Metaclass for all models"
384    def __new__(cls, name, bases, attrs):
385        # If this isn't a subclass of Model, don't do anything special.
386        if not bases:
387            return type.__new__(cls, name, bases, attrs)
388
389        # If this model is a subclass of another Model, create an Options
390        # object by first copying the base class's _meta and then updating it
391        # with the overrides from this class.
392        replaces_module = None
393        if bases[0] != Model:
394            if not attrs.has_key('fields'):
395                attrs['fields'] = list(bases[0]._meta._orig_init_args['fields'][:])
396            if attrs.has_key('ignore_fields'):
397                ignore_fields = attrs.pop('ignore_fields')
398                new_fields = []
399                for i, f in enumerate(attrs['fields']):
400                    if f.name not in ignore_fields:
401                        new_fields.append(f)
402                attrs['fields'] = new_fields
403            if attrs.has_key('add_fields'):
404                attrs['fields'].extend(attrs.pop('add_fields'))
405            if attrs.has_key('replaces_module'):
406                # Set the replaces_module variable for now. We can't actually
407                # do anything with it yet, because the module hasn't yet been
408                # created.
409                replaces_module = attrs.pop('replaces_module').split('.')
410            # Pass any Options overrides to the base's Options instance, and
411            # simultaneously remove them from attrs. When this is done, attrs
412            # will be a dictionary of custom methods, plus __module__.
413            meta_overrides = {}
414            for k, v in attrs.items():
415                if not callable(v) and k != '__module__':
416                    meta_overrides[k] = attrs.pop(k)
417            opts = bases[0]._meta.copy(**meta_overrides)
418            opts.object_name = name
419            del meta_overrides
420        else:
421            opts = Options(
422                # If the module_name wasn't given, use the class name
423                # in lowercase, plus a trailing "s" -- a poor-man's
424                # pluralization.
425                module_name = attrs.pop('module_name', name.lower() + 's'),
426                # If the verbose_name wasn't given, use the class name,
427                # converted from InitialCaps to "lowercase with spaces".
428                verbose_name = attrs.pop('verbose_name',
429                    re.sub('([A-Z])', ' \\1', name).lower().strip()),
430                verbose_name_plural = attrs.pop('verbose_name_plural', ''),
431                db_table = attrs.pop('db_table', ''),
432                fields = attrs.pop('fields'),
433                ordering = attrs.pop('ordering', None),
434                unique_together = attrs.pop('unique_together', None),
435                admin = attrs.pop('admin', None),
436                has_related_links = attrs.pop('has_related_links', False),
437                where_constraints = attrs.pop('where_constraints', None),
438                object_name = name,
439                app_label = attrs.pop('app_label', None),
440                exceptions = attrs.pop('exceptions', None),
441                permissions = attrs.pop('permissions', None),
442                get_latest_by = attrs.pop('get_latest_by', None),
443                order_with_respect_to = attrs.pop('order_with_respect_to', None),
444                module_constants = attrs.pop('module_constants', None),
445            )
446
447        # Dynamically create the module that will contain this class and its
448        # associated helper functions.
449        if replaces_module is not None:
450            new_mod = get_module(*replaces_module)
451        else:
452            new_mod = types.ModuleType(opts.module_name)
453
454        # Collect any/all custom class methods and module functions, and move
455        # them to a temporary holding variable. We'll deal with them later.
456        if replaces_module is not None:
457            # Initialize these values to the base class' custom_methods and
458            # custom_functions.
459            custom_methods = dict([(k, v) for k, v in new_mod.Klass.__dict__.items() if hasattr(v, 'custom')])
460            custom_functions = dict([(k, v) for k, v in new_mod.__dict__.items() if hasattr(v, 'custom')])
461        else:
462            custom_methods, custom_functions = {}, {}
463        manipulator_methods = {}
464        for k, v in attrs.items():
465            if k in ('__module__', '__init__', '_overrides', '__doc__'):
466                continue # Skip the important stuff.
467            # Give the function a function attribute "custom" to designate that
468            # it's a custom function/method.
469            v.custom = True
470            if k.startswith(MODEL_FUNCTIONS_PREFIX):
471                custom_functions[k[len(MODEL_FUNCTIONS_PREFIX):]] = v
472            elif k.startswith(MANIPULATOR_FUNCTIONS_PREFIX):
473                manipulator_methods[k[len(MANIPULATOR_FUNCTIONS_PREFIX):]] = v
474            else:
475                custom_methods[k] = v
476            del attrs[k]
477
478        # Create the module-level ObjectDoesNotExist exception.
479        dne_exc_name = '%sDoesNotExist' % name
480        does_not_exist_exception = types.ClassType(dne_exc_name, (ObjectDoesNotExist,), {})
481        # Explicitly set its __module__ because it will initially (incorrectly)
482        # be set to the module the code is being executed in.
483        does_not_exist_exception.__module__ = MODEL_PREFIX + '.' + opts.module_name
484        setattr(new_mod, dne_exc_name, does_not_exist_exception)
485
486        # Create other exceptions.
487        for exception_name in opts.exceptions:
488            exc = types.ClassType(exception_name, (Exception,), {})
489            exc.__module__ = MODEL_PREFIX + '.' + opts.module_name # Set this explicitly, as above.
490            setattr(new_mod, exception_name, exc)
491
492        # Create any module-level constants, if applicable.
493        for k, v in opts.module_constants.items():
494            setattr(new_mod, k, v)
495
496        # Create the default class methods.
497        attrs['__init__'] = curry(method_init, opts)
498        attrs['__eq__'] = curry(method_eq, opts)
499        attrs['save'] = curry(method_save, opts)
500        attrs['save'].alters_data = True
501        attrs['delete'] = curry(method_delete, opts)
502        attrs['delete'].alters_data = True
503
504        if opts.order_with_respect_to:
505            attrs['get_next_in_order'] = curry(method_get_next_in_order, opts, opts.order_with_respect_to)
506            attrs['get_previous_in_order'] = curry(method_get_previous_in_order, opts, opts.order_with_respect_to)
507
508        for f in opts.fields:
509            # If the object has a relationship to itself, as designated by
510            # RECURSIVE_RELATIONSHIP_CONSTANT, create that relationship formally.
511            if f.rel and f.rel.to == RECURSIVE_RELATIONSHIP_CONSTANT:
512                f.rel.to = opts
513                f.name = f.name or ((f.rel.name or f.rel.to.object_name.lower()) + '_' + f.rel.to.pk.name)
514                f.verbose_name = f.verbose_name or f.rel.to.verbose_name
515                f.rel.field_name = f.rel.field_name or f.rel.to.pk.name
516            # Add "get_thingie" methods for many-to-one related objects.
517            # EXAMPLES: Choice.get_poll(), Story.get_dateline()
518            if isinstance(f.rel, ManyToOne):
519                func = curry(method_get_many_to_one, f)
520                func.__doc__ = "Returns the associated `%s.%s` object." % (f.rel.to.app_label, f.rel.to.module_name)
521                attrs['get_%s' % f.rel.name] = func
522
523        for f in opts.many_to_many:
524            # Add "get_thingie" methods for many-to-many related objects.
525            # EXAMPLES: Poll.get_site_list(), Story.get_byline_list()
526            func = curry(method_get_many_to_many, f)
527            func.__doc__ = "Returns a list of associated `%s.%s` objects." % (f.rel.to.app_label, f.rel.to.module_name)
528            attrs['get_%s_list' % f.rel.name] = func
529            # Add "set_thingie" methods for many-to-many related objects.
530            # EXAMPLES: Poll.set_sites(), Story.set_bylines()
531            func = curry(method_set_many_to_many, f)
532            func.__doc__ = "Resets this object's `%s.%s` list to the given list of IDs. Note that it doesn't check whether the given IDs are valid." % (f.rel.to.app_label, f.rel.to.module_name)
533            func.alters_data = True
534            attrs['set_%s' % f.name] = func
535
536        # Create the class, because we need it to use in currying.
537        new_class = type.__new__(cls, name, bases, attrs)
538
539        # Give the class a docstring -- its definition.
540        new_class.__doc__ = "%s.%s(%s)" % (opts.module_name, name, ", ".join([f.name for f in opts.fields]))
541
542        # Create the standard, module-level API helper functions such
543        # as get_object() and get_list().
544        new_mod.get_object = curry(function_get_object, opts, new_class, does_not_exist_exception)
545        new_mod.get_object.__doc__ = "Returns the %s object matching the given parameters." % name
546
547        new_mod.get_list = curry(function_get_list, opts, new_class)
548        new_mod.get_list.__doc__ = "Returns a list of %s objects matching the given parameters." % name
549
550        new_mod.get_iterator = curry(function_get_iterator, opts, new_class)
551        new_mod.get_iterator.__doc__ = "Returns an iterator of %s objects matching the given parameters." % name
552
553        new_mod.get_values = curry(function_get_values, opts, new_class)
554        new_mod.get_values.__doc__ = "Returns a list of dictionaries matching the given parameters."
555
556        new_mod.get_values_iterator = curry(function_get_values_iterator, opts, new_class)
557        new_mod.get_values_iterator.__doc__ = "Returns an iterator of dictionaries matching the given parameters."
558
559        new_mod.get_count = curry(function_get_count, opts)
560        new_mod.get_count.__doc__ = "Returns the number of %s objects matching the given parameters." % name
561
562        new_mod._get_sql_clause = curry(function_get_sql_clause, opts)
563
564        new_mod.get_in_bulk = curry(function_get_in_bulk, opts, new_class)
565        new_mod.get_in_bulk.__doc__ = "Returns a dictionary of ID -> %s for the %s objects with IDs in the given id_list." % (name, name)
566
567        if opts.get_latest_by:
568            new_mod.get_latest = curry(function_get_latest, opts, new_class, does_not_exist_exception)
569
570        for f in opts.fields:
571            if isinstance(f, DateField) or isinstance(f, DateTimeField):
572                # Add "get_next_by_thingie" and "get_previous_by_thingie" methods
573                # for all DateFields and DateTimeFields that cannot be null.
574                # EXAMPLES: Poll.get_next_by_pub_date(), Poll.get_previous_by_pub_date()
575                if not f.null:
576                    setattr(new_class, 'get_next_by_%s' % f.name, curry(method_get_next_or_previous, new_mod.get_object, f, True))
577                    setattr(new_class, 'get_previous_by_%s' % f.name, curry(method_get_next_or_previous, new_mod.get_object, f, False))
578                # Add "get_thingie_list" for all DateFields and DateTimeFields.
579                # EXAMPLE: polls.get_pub_date_list()
580                func = curry(function_get_date_list, opts, f)
581                func.__doc__ = "Returns a list of days, months or years (as datetime.datetime objects) in which %s objects are available. The first parameter ('kind') must be one of 'year', 'month' or 'day'." % name
582                setattr(new_mod, 'get_%s_list' % f.name, func)
583
584            elif isinstance(f, FileField):
585                setattr(new_class, 'get_%s_filename' % f.name, curry(method_get_file_filename, f))
586                setattr(new_class, 'get_%s_url' % f.name, curry(method_get_file_url, f))
587                setattr(new_class, 'get_%s_size' % f.name, curry(method_get_file_size, f))
588                func = curry(method_save_file, f)
589                func.alters_data = True
590                setattr(new_class, 'save_%s_file' % f.name, func)
591                if isinstance(f, ImageField):
592                    # Add get_BLAH_width and get_BLAH_height methods, but only
593                    # if the image field doesn't have width and height cache
594                    # fields.
595                    if not f.width_field:
596                        setattr(new_class, 'get_%s_width' % f.name, curry(method_get_image_width, f))
597                    if not f.height_field:
598                        setattr(new_class, 'get_%s_height' % f.name, curry(method_get_image_height, f))
599
600        # Add the class itself to the new module we've created.
601        new_mod.__dict__[name] = new_class
602
603        # Add "Klass" -- a shortcut reference to the class.
604        new_mod.__dict__['Klass'] = new_class
605
606        # Add the Manipulators.
607        new_mod.__dict__['AddManipulator'] = get_manipulator(opts, new_class, manipulator_methods, add=True)
608        new_mod.__dict__['ChangeManipulator'] = get_manipulator(opts, new_class, manipulator_methods, change=True)
609
610        # Now that we have references to new_mod and new_class, we can add
611        # any/all extra class methods to the new class. Note that we could
612        # have just left the extra methods in attrs (above), but that would
613        # have meant that any code within the extra methods would *not* have
614        # access to module-level globals, such as get_list(), db, etc.
615        # In order to give these methods access to those globals, we have to
616        # deconstruct the method getting its raw "code" object, then recreating
617        # the function with a new "globals" dictionary.
618        #
619        # To complicate matters more, because each method is manually assigned
620        # a "globals" value, that "globals" value does NOT include the methods
621        # that haven't been created yet. For instance, if there are two custom
622        # methods, foo() and bar(), and foo() is created first, it won't have
623        # bar() within its globals(). This is a problem because sometimes
624        # custom methods/functions refer to other custom methods/functions. To
625        # solve this problem, we keep track of the new functions created (in
626        # the new_functions variable) and manually append each new function to
627        # the func_globals() of all previously-created functions. So, by the
628        # end of the loop, all functions will "know" about all the other
629        # functions.
630        _reassign_globals(custom_methods, new_mod, new_class)
631        _reassign_globals(custom_functions, new_mod, new_mod)
632        _reassign_globals(manipulator_methods, new_mod, new_mod.__dict__['AddManipulator'])
633        _reassign_globals(manipulator_methods, new_mod, new_mod.__dict__['ChangeManipulator'])
634
635        if hasattr(new_class, 'get_absolute_url'):
636            new_class.get_absolute_url = curry(get_absolute_url, opts, new_class.get_absolute_url)
637
638        # Get a reference to the module the class is in, and dynamically add
639        # the new module to it.
640        app_package = sys.modules.get(new_class.__module__)
641        if replaces_module is not None:
642            app_label = replaces_module[0]
643        else:
644            app_package.__dict__[opts.module_name] = new_mod
645            app_label = app_package.__name__[app_package.__name__.rfind('.')+1:]
646
647            # Populate the _MODELS member on the module the class is in.
648            # Example: django.models.polls will have a _MODELS member that will
649            # contain this list:
650            # [<class 'django.models.polls.Poll'>, <class 'django.models.polls.Choice'>]
651            # Don't do this if replaces_module is set.
652            app_package.__dict__.setdefault('_MODELS', []).append(new_class)
653
654        # Cache the app label.
655        opts.app_label = app_label
656
657        # If the db_table wasn't provided, use the app_label + module_name.
658        if not opts.db_table:
659            opts.db_table = "%s_%s" % (app_label, opts.module_name)
660        new_class._meta = opts
661
662        # Set the __file__ attribute to the __file__ attribute of its package,
663        # because they're technically from the same file. Note: if we didn't
664        # set this, sys.modules would think this module was built-in.
665        try:
666            new_mod.__file__ = app_package.__file__
667        except AttributeError:
668            # 'module' object has no attribute '__file__', which means the
669            # class was probably being entered via the interactive interpreter.
670            pass
671
672        # Add the module's entry to sys.modules -- for instance,
673        # "django.models.polls.polls". Note that "django.models.polls" has already
674        # been added automatically.
675        sys.modules.setdefault('%s.%s.%s' % (MODEL_PREFIX, app_label, opts.module_name), new_mod)
676
677        # If this module replaces another one, get a reference to the other
678        # module's parent, and replace the other module with the one we've just
679        # created.
680        if replaces_module is not None:
681            old_app = get_app(replaces_module[0])
682            setattr(old_app, replaces_module[1], new_mod)
683            for i, model in enumerate(old_app._MODELS):
684                if model._meta.module_name == replaces_module[1]:
685                    # Replace the appropriate member of the old app's _MODELS
686                    # data structure.
687                    old_app._MODELS[i] = new_class
688                    # Replace all relationships to the old class with
689                    # relationships to the new one.
690                    for rel_opts, rel_field in model._meta.get_all_related_objects():
691                        rel_field.rel.to = opts
692                    for rel_opts, rel_field in model._meta.get_all_related_many_to_many_objects():
693                        rel_field.rel.to = opts
694                    break
695
696        return new_class
697
698class Model:
699    __metaclass__ = ModelBase
700
701    def __repr__(self):
702        return '<%s object>' % self.__class__.__name__
703
704############################################
705# HELPER FUNCTIONS (CURRIED MODEL METHODS) #
706############################################
707
708# CORE METHODS #############################
709
710def method_init(opts, self, *args, **kwargs):
711    if kwargs:
712        for f in opts.fields:
713            setattr(self, f.name, kwargs.pop(f.name, f.get_default()))
714        if kwargs:
715            raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
716    for i, arg in enumerate(args):
717        setattr(self, opts.fields[i].name, arg)
718
719def method_eq(opts, self, other):
720    return isinstance(other, self.__class__) and getattr(self, opts.pk.name) == getattr(other, opts.pk.name)
721
722def method_save(opts, self):
723    # Run any pre-save hooks.
724    if hasattr(self, '_pre_save'):
725        self._pre_save()
726    non_pks = [f for f in opts.fields if not f.primary_key]
727    cursor = db.db.cursor()
728
729    # First, try an UPDATE. If that doesn't update anything, do an INSERT.
730    pk_set = bool(getattr(self, opts.pk.name))
731    if pk_set:
732        db_values = [f.get_db_prep_save(f.pre_save(getattr(self, f.name), False)) for f in non_pks]
733        cursor.execute("UPDATE %s SET %s WHERE %s=%%s" % (opts.db_table,
734            ','.join(['%s=%%s' % f.name for f in non_pks]), opts.pk.name),
735            db_values + [getattr(self, opts.pk.name)])
736    if not pk_set or cursor.rowcount == 0:
737        field_names = [f.name for f in opts.fields if not isinstance(f, AutoField)]
738        placeholders = ['%s'] * len(field_names)
739        db_values = [f.get_db_prep_save(f.pre_save(getattr(self, f.name), True)) for f in opts.fields if not isinstance(f, AutoField)]
740        if opts.order_with_respect_to:
741            field_names.append('_order')
742            # TODO: This assumes the database supports subqueries.
743            placeholders.append('(SELECT COUNT(*) FROM %s WHERE %s = %%s)' % \
744                (opts.db_table, opts.order_with_respect_to.name))
745            db_values.append(getattr(self, opts.order_with_respect_to.name))
746        cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % (opts.db_table,
747            ','.join(field_names), ','.join(placeholders)), db_values)
748        if opts.has_auto_field:
749            setattr(self, opts.pk.name, db.get_last_insert_id(cursor, opts.db_table, opts.pk.name))
750    db.db.commit()
751    # Run any post-save hooks.
752    if hasattr(self, '_post_save'):
753        self._post_save()
754
755def method_delete(opts, self):
756    assert getattr(self, opts.pk.name) is not None, "%r can't be deleted because it doesn't have an ID."
757    # Run any pre-delete hooks.
758    if hasattr(self, '_pre_delete'):
759        self._pre_delete()
760    cursor = db.db.cursor()
761    for rel_opts, rel_field in opts.get_all_related_objects():
762        rel_opts_name = opts.get_rel_object_method_name(rel_opts, rel_field)
763        if isinstance(rel_field.rel, OneToOne):
764            try:
765                sub_obj = getattr(self, 'get_%s' % rel_opts_name)()
766            except ObjectDoesNotExist:
767                pass
768            else:
769                sub_obj.delete()
770        else:
771            for sub_obj in getattr(self, 'get_%s_list' % rel_opts_name)():
772                sub_obj.delete()
773    for rel_opts, rel_field in opts.get_all_related_many_to_many_objects():
774        cursor.execute("DELETE FROM %s WHERE %s_id=%%s" % (rel_field.get_m2m_db_table(rel_opts),
775            self._meta.object_name.lower()), [getattr(self, opts.pk.name)])
776    for f in opts.many_to_many:
777        cursor.execute("DELETE FROM %s WHERE %s_id=%%s" % (f.get_m2m_db_table(opts), self._meta.object_name.lower()),
778            [getattr(self, opts.pk.name)])
779    cursor.execute("DELETE FROM %s WHERE %s=%%s" % (opts.db_table, opts.pk.name), [getattr(self, opts.pk.name)])
780    db.db.commit()
781    setattr(self, opts.pk.name, None)
782    for f in opts.fields:
783        if isinstance(f, FileField) and getattr(self, f.name):
784            file_name = getattr(self, 'get_%s_filename' % f.name)()
785            # If the file exists and no other object of this type references it,
786            # delete it from the filesystem.
787            if os.path.exists(file_name) and not opts.get_model_module().get_list(**{'%s__exact' % f.name: getattr(self, f.name)}):
788                os.remove(file_name)
789    # Run any post-delete hooks.
790    if hasattr(self, '_post_delete'):
791        self._post_delete()
792
793def method_get_next_in_order(opts, order_field, self):
794    if not hasattr(self, '_next_in_order_cache'):
795        self._next_in_order_cache = opts.get_model_module().get_object(order_by=('_order',),
796            where=['_order > (SELECT _order FROM %s WHERE %s=%%s)' % (opts.db_table, opts.pk.name),
797                '%s=%%s' % order_field.name], limit=1,
798            params=[getattr(self, opts.pk.name), getattr(self, order_field.name)])
799    return self._next_in_order_cache
800
801def method_get_previous_in_order(opts, order_field, self):
802    if not hasattr(self, '_previous_in_order_cache'):
803        self._previous_in_order_cache = opts.get_model_module().get_object(order_by=('-_order',),
804            where=['_order < (SELECT _order FROM %s WHERE %s=%%s)' % (opts.db_table, opts.pk.name),
805                '%s=%%s' % order_field.name], limit=1,
806            params=[getattr(self, opts.pk.name), getattr(self, order_field.name)])
807    return self._previous_in_order_cache
808
809# RELATIONSHIP METHODS #####################
810
811# Example: Story.get_dateline()
812def method_get_many_to_one(field_with_rel, self):
813    cache_var = field_with_rel.rel.get_cache_name()
814    if not hasattr(self, cache_var):
815        val = getattr(self, field_with_rel.name)
816        mod = field_with_rel.rel.to.get_model_module()
817        if val is None:
818            raise getattr(mod, '%sDoesNotExist' % field_with_rel.rel.to.object_name)
819        retrieved_obj = mod.get_object(**{'%s__exact' % field_with_rel.rel.field_name: val})
820        setattr(self, cache_var, retrieved_obj)
821    return getattr(self, cache_var)
822
823# Handles getting many-to-many related objects.
824# Example: Poll.get_site_list()
825def method_get_many_to_many(field_with_rel, self):
826    rel = field_with_rel.rel.to
827    cache_var = '_%s_cache' % field_with_rel.name
828    if not hasattr(self, cache_var):
829        mod = rel.get_model_module()
830        sql = "SELECT %s FROM %s a, %s b WHERE a.%s = b.%s_id AND b.%s_id = %%s %s" % \
831            (','.join(['a.%s' % f.name for f in rel.fields]), rel.db_table,
832            field_with_rel.get_m2m_db_table(self._meta), rel.pk.name,
833            rel.object_name.lower(), self._meta.object_name.lower(), rel.get_order_sql('a'))
834        cursor = db.db.cursor()
835        cursor.execute(sql, [getattr(self, self._meta.pk.name)])
836        setattr(self, cache_var, [getattr(mod, rel.object_name)(*row) for row in cursor.fetchall()])
837    return getattr(self, cache_var)
838
839# Handles setting many-to-many relationships.
840# Example: Poll.set_sites()
841def method_set_many_to_many(rel_field, self, id_list):
842    id_list = map(int, id_list) # normalize to integers
843    current_ids = [obj.id for obj in method_get_many_to_many(rel_field, self)]
844    ids_to_add, ids_to_delete = dict([(i, 1) for i in id_list]), []
845    for current_id in current_ids:
846        if current_id in id_list:
847            del ids_to_add[current_id]
848        else:
849            ids_to_delete.append(current_id)
850    ids_to_add = ids_to_add.keys()
851    # Now ids_to_add is a list of IDs to add, and ids_to_delete is a list of IDs to delete.
852    if not ids_to_delete and not ids_to_add:
853        return False # No change
854    rel = rel_field.rel.to
855    m2m_table = rel_field.get_m2m_db_table(self._meta)
856    cursor = db.db.cursor()
857    this_id = getattr(self, self._meta.pk.name)
858    if ids_to_delete:
859        sql = "DELETE FROM %s WHERE %s_id = %%s AND %s_id IN (%s)" % (m2m_table, self._meta.object_name.lower(), rel.object_name.lower(), ','.join(map(str, ids_to_delete)))
860        cursor.execute(sql, [this_id])
861    if ids_to_add:
862        sql = "INSERT INTO %s (%s_id, %s_id) VALUES (%%s, %%s)" % (m2m_table, self._meta.object_name.lower(), rel.object_name.lower())
863        cursor.executemany(sql, [(this_id, i) for i in ids_to_add])
864    db.db.commit()
865    try:
866        delattr(self, '_%s_cache' % rel_field.name) # clear cache, if it exists
867    except AttributeError:
868        pass
869    return True
870
871# Handles related-object retrieval.
872# Examples: Poll.get_choice(), Poll.get_choice_list(), Poll.get_choice_count()
873def method_get_related(method_name, rel_mod, rel_field, self, **kwargs):
874    kwargs['%s__exact' % rel_field.name] = getattr(self, rel_field.rel.field_name)
875    kwargs.update(rel_field.rel.lookup_overrides)
876    return getattr(rel_mod, method_name)(**kwargs)
877
878# Handles adding related objects.
879# Example: Poll.add_choice()
880def method_add_related(rel_obj, rel_mod, rel_field, self, *args, **kwargs):
881    init_kwargs = dict(zip([f.name for f in rel_obj.fields if f != rel_field and not isinstance(f, AutoField)], args))
882    init_kwargs.update(kwargs)
883    for f in rel_obj.fields:
884        if isinstance(f, AutoField):
885            init_kwargs[f.name] = None
886    init_kwargs[rel_field.name] = getattr(self, rel_field.rel.field_name)
887    obj = rel_mod.Klass(**init_kwargs)
888    obj.save()
889    return obj
890
891# Handles related many-to-many object retrieval.
892# Examples: Album.get_song(), Album.get_song_list(), Album.get_song_count()
893def method_get_related_many_to_many(method_name, rel_mod, rel_field, self, **kwargs):
894    kwargs['%s__id__exact' % rel_field.name] = self.id
895    return getattr(rel_mod, method_name)(**kwargs)
896
897# Handles setting many-to-many related objects.
898# Example: Album.set_songs()
899def method_set_related_many_to_many(rel_opts, rel_field, self, id_list):
900    id_list = map(int, id_list) # normalize to integers
901    rel = rel_field.rel.to
902    m2m_table = rel_field.get_m2m_db_table(rel_opts)
903    this_id = getattr(self, self._meta.pk.name)
904    cursor = db.db.cursor()
905    cursor.execute("DELETE FROM %s WHERE %s_id = %%s" % (m2m_table, rel.object_name.lower()), [this_id])
906    sql = "INSERT INTO %s (%s_id, %s_id) VALUES (%%s, %%s)" % (m2m_table, rel.object_name.lower(), rel_opts.object_name.lower())
907    cursor.executemany(sql, [(this_id, i) for i in id_list])
908    db.db.commit()
909
910# ORDERING METHODS #########################
911
912def method_set_order(ordered_obj, self, id_list):
913    cursor = db.db.cursor()
914    # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s"
915    sql = "UPDATE %s SET _order = %%s WHERE %s = %%s AND %s = %%s" % (ordered_obj.db_table, ordered_obj.order_with_respect_to.name, ordered_obj.pk.name)
916    rel_val = getattr(self, ordered_obj.order_with_respect_to.rel.field_name)
917    cursor.executemany(sql, [(i, rel_val, j) for i, j in enumerate(id_list)])
918    db.db.commit()
919
920def method_get_order(ordered_obj, self):
921    cursor = db.db.cursor()
922    # Example: "SELECT id FROM poll_choices WHERE poll_id = %s ORDER BY _order"
923    sql = "SELECT %s FROM %s WHERE %s = %%s ORDER BY _order" % (ordered_obj.pk.name, ordered_obj.db_table, ordered_obj.order_with_respect_to.name)
924    rel_val = getattr(self, ordered_obj.order_with_respect_to.rel.field_name)
925    cursor.execute(sql, [rel_val])
926    return [r[0] for r in cursor.fetchall()]
927
928# DATE-RELATED METHODS #####################
929
930def method_get_next_or_previous(get_object_func, field, is_next, self, **kwargs):
931    kwargs.setdefault('where', []).append('%s %s %%s' % (field.name, (is_next and '>' or '<')))
932    kwargs.setdefault('params', []).append(str(getattr(self, field.name)))
933    kwargs['order_by'] = [(not is_next and '-' or '') + field.name]
934    kwargs['limit'] = 1
935    return get_object_func(**kwargs)
936
937# FILE-RELATED METHODS #####################
938
939def method_get_file_filename(field, self):
940    return os.path.join(settings.MEDIA_ROOT, getattr(self, field.name))
941
942def method_get_file_url(field, self):
943    if getattr(self, field.name): # value is not blank
944        import urlparse
945        return urlparse.urljoin(settings.MEDIA_URL, getattr(self, field.name))
946    return ''
947
948def method_get_file_size(field, self):
949    return os.path.getsize(method_get_file_filename(field, self))
950
951def method_save_file(field, self, filename, raw_contents):
952    directory = field.get_directory_name()
953    try: # Create the date-based directory if it doesn't exist.
954        os.makedirs(os.path.join(settings.MEDIA_ROOT, directory))
955    except OSError: # Directory probably already exists.
956        pass
957    filename = field.get_filename(filename)
958
959    # If the filename already exists, keep adding an underscore to the name of
960    # the file until the filename doesn't exist.
961    while os.path.exists(os.path.join(settings.MEDIA_ROOT, filename)):
962        try:
963            dot_index = filename.rindex('.')
964        except ValueError: # filename has no dot
965            filename += '_'
966        else:
967            filename = filename[:dot_index] + '_' + filename[dot_index:]
968
969    # Write the file to disk.
970    setattr(self, field.name, filename)
971    fp = open(getattr(self, 'get_%s_filename' % field.name)(), 'wb')
972    fp.write(raw_contents)
973    fp.close()
974
975    # Save the width and/or height, if applicable.
976    if isinstance(field, ImageField) and (field.width_field or field.height_field):
977        from django.utils.images import get_image_dimensions
978        width, height = get_image_dimensions(getattr(self, 'get_%s_filename' % field.name)())
979        if field.width_field:
980            setattr(self, field.width_field, width)
981        if field.height_field:
982            setattr(self, field.height_field, height)
983
984    # Save the object, because it has changed.
985    self.save()
986
987# IMAGE FIELD METHODS ######################
988
989def method_get_image_width(field, self):
990    return _get_image_dimensions(field, self)[0]
991
992def method_get_image_height(field, self):
993    return _get_image_dimensions(field, self)[1]
994
995def _get_image_dimensions(field, self):
996    cachename = "__%s_dimensions_cache" % field.name
997    if not hasattr(self, cachename):
998        from django.utils.images import get_image_dimensions
999        fname = getattr(self, "get_%s_filename" % field.name)()
1000        setattr(self, cachename, get_image_dimensions(fname))
1001    return getattr(self, cachename)
1002
1003##############################################
1004# HELPER FUNCTIONS (CURRIED MODEL FUNCTIONS) #
1005##############################################
1006
1007def get_absolute_url(opts, func, self):
1008    return settings.ABSOLUTE_URL_OVERRIDES.get('%s.%s' % (opts.app_label, opts.module_name), func)(self)
1009
1010def _get_where_clause(lookup_type, table_prefix, field_name, value):
1011    try:
1012        return '%s%s %s %%s' % (table_prefix, field_name, db.OPERATOR_MAPPING[lookup_type])
1013    except KeyError:
1014        pass
1015    if lookup_type == 'in':
1016        return '%s%s IN (%s)' % (table_prefix, field_name, ','.join(['%s' for v in value]))
1017    elif lookup_type in ('range', 'year'):
1018        return '%s%s BETWEEN %%s AND %%s' % (table_prefix, field_name)
1019    elif lookup_type in ('month', 'day'):
1020        return "%s = %%s" % db.get_date_extract_sql(lookup_type, table_prefix + field_name)
1021    elif lookup_type == 'isnull':
1022        return "%s%s IS %sNULL" % (table_prefix, field_name, (not value and 'NOT ' or ''))
1023    raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type)
1024
1025def function_get_object(opts, klass, does_not_exist_exception, **kwargs):
1026    obj_list = function_get_list(opts, klass, **kwargs)
1027    if len(obj_list) < 1:
1028        raise does_not_exist_exception, "%s does not exist for %s" % (opts.object_name, kwargs)
1029    assert len(obj_list) == 1, "get_object() returned more than one %s -- it returned %s! Lookup parameters were %s" % (opts.object_name, len(obj_list), kwargs)
1030    return obj_list[0]
1031
1032def _get_cached_row(opts, row, index_start):
1033    "Helper function that recursively returns an object with cache filled"
1034    index_end = index_start + len(opts.fields)
1035    obj = opts.get_model_module().Klass(*row[index_start:index_end])
1036    for f in opts.fields:
1037        if f.rel and not f.null:
1038            rel_obj, index_end = _get_cached_row(f.rel.to, row, index_end)
1039            setattr(obj, f.rel.get_cache_name(), rel_obj)
1040    return obj, index_end
1041
1042def function_get_iterator(opts, klass, **kwargs):
1043    # kwargs['select'] is a dictionary, and dictionaries' key order is
1044    # undefined, so we convert it to a list of tuples internally.
1045    kwargs['select'] = kwargs.get('select', {}).items()
1046
1047    cursor = db.db.cursor()
1048    select, sql, params, full_query = function_get_sql_clause(opts, **kwargs)
1049    cursor.execute(full_query, params)
1050    fill_cache = kwargs.get('select_related')
1051    index_end = len(opts.fields)
1052    while 1:
1053        rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)
1054        if not rows:
1055            raise StopIteration
1056        for row in rows:
1057            if fill_cache:
1058                obj, index_end = _get_cached_row(opts, row, 0)
1059            else:
1060                obj = klass(*row[:index_end])
1061            for i, k in enumerate(kwargs['select']):
1062                setattr(obj, k[0], row[index_end+i])
1063            yield obj
1064
1065def function_get_list(opts, klass, **kwargs):
1066    return list(function_get_iterator(opts, klass, **kwargs))
1067
1068def function_get_count(opts, **kwargs):
1069    kwargs['order_by'] = []
1070    kwargs['offset'] = None
1071    kwargs['limit'] = None
1072    kwargs['select_related'] = False
1073    _, sql, params, full_query = function_get_sql_clause(opts, **kwargs)
1074    cursor = db.db.cursor()
1075    cursor.execute("SELECT COUNT(*)" + sql, params)
1076    return cursor.fetchone()[0]
1077
1078def function_get_values_iterator(opts, klass, **kwargs):
1079    # select_related and select aren't supported in get_values().
1080    kwargs['select_related'] = False
1081    kwargs['select'] = {}
1082
1083    # 'fields' is a list of field names to fetch.
1084    try:
1085        fields = kwargs.pop('fields')
1086    except KeyError: # Default to all fields.
1087        fields = [f.name for f in opts.fields]
1088
1089    cursor = db.db.cursor()
1090    _, sql, params, full_query = function_get_sql_clause(opts, **kwargs)
1091    select = ['%s.%s' % (opts.db_table, f) for f in fields]
1092    cursor.execute("SELECT " + (kwargs.get('distinct') and "DISTINCT " or "") + ",".join(select) + sql, params)
1093    while 1:
1094        rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)
1095        if not rows:
1096            raise StopIteration
1097        for row in rows:
1098            yield dict(zip(fields, row))
1099
1100def function_get_values(opts, klass, **kwargs):
1101    return list(function_get_values_iterator(opts, klass, **kwargs))
1102
1103def _fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen):
1104    """
1105    Helper function that recursively populates the select, tables and where (in
1106    place) for fill-cache queries.
1107    """
1108    for f in opts.fields:
1109        if f.rel and not f.null:
1110            db_table = f.rel.to.db_table
1111            if db_table not in cache_tables_seen:
1112                tables.append(db_table)
1113            else: # The table was already seen, so give it a table alias.
1114                new_prefix = '%s%s' % (db_table, len(cache_tables_seen))
1115                tables.append('%s %s' % (db_table, new_prefix))
1116                db_table = new_prefix
1117            cache_tables_seen.append(db_table)
1118            where.append('%s.%s = %s.%s' % (old_prefix, f.name, db_table, f.rel.field_name))
1119            select.extend(['%s.%s as "%s.%s"' % (db_table, f2.name, db_table, f2.name) for f2 in f.rel.to.fields])
1120            _fill_table_cache(f.rel.to, select, tables, where, db_table, cache_tables_seen)
1121
1122def _throw_bad_kwarg_error(kwarg):
1123    # Helper function to remove redundancy.
1124    raise TypeError, "got unexpected keyword argument '%s'" % kwarg
1125
1126def _parse_lookup(kwarg_items, opts, table_count=0):
1127    # Helper function that handles converting API kwargs (e.g.
1128    # "name__exact": "tom") to SQL.
1129
1130    # Note that there is a distinction between where and join_where. The latter
1131    # is specifically a list of where clauses to use for JOINs. This
1132    # distinction is necessary because of support for "_or".
1133
1134    # table_count is used to ensure table aliases are unique.
1135    tables, join_where, where, params = [], [], [], []
1136    for kwarg, kwarg_value in kwarg_items:
1137        if kwarg in ('order_by', 'limit', 'offset', 'select_related', 'distinct', 'select', 'tables', 'where', 'params'):
1138            continue
1139        if kwarg_value is None:
1140            continue
1141        if kwarg == '_or':
1142            for val in kwarg_value:
1143                tables2, join_where2, where2, params2, table_count = _parse_lookup(val, opts, table_count)
1144                tables.extend(tables2)
1145                join_where.extend(join_where2)
1146                where.append('(%s)' % ' OR '.join(where2))
1147                params.extend(params2)
1148            continue
1149        lookup_list = kwarg.split(LOOKUP_SEPARATOR)
1150        # pk="value" is shorthand for (primary key)__exact="value"
1151        if lookup_list[-1] == 'pk':
1152            lookup_list = lookup_list[:-1] + [opts.pk.name, 'exact']
1153        if len(lookup_list) == 1:
1154            _throw_bad_kwarg_error(kwarg)
1155        lookup_type = lookup_list.pop()
1156        current_opts = opts # We'll be overwriting this, so keep a reference to the original opts.
1157        current_table_alias = current_opts.db_table
1158        param_required = False
1159        while lookup_list or param_required:
1160            table_count += 1
1161            try:
1162                # "current" is a piece of the lookup list. For example, in
1163                # choices.get_list(poll__sites__id__exact=5), lookup_list is
1164                # ["polls", "sites", "id"], and the first current is "polls".
1165                try:
1166                    current = lookup_list.pop(0)
1167                except IndexError:
1168                    # If we're here, lookup_list is empty but param_required
1169                    # is set to True, which means the kwarg was bad.
1170                    # Example: choices.get_list(poll__exact='foo')
1171                    _throw_bad_kwarg_error(kwarg)
1172                # Try many-to-many relationships first...
1173                for f in current_opts.many_to_many:
1174                    if f.name == current:
1175                        rel_table_alias = 't%s' % table_count
1176                        table_count += 1
1177                        tables.append('%s %s' % (f.get_m2m_db_table(current_opts), rel_table_alias))
1178                        join_where.append('%s.%s = %s.%s_id' % (current_table_alias, current_opts.pk.name,
1179                            rel_table_alias, current_opts.object_name.lower()))
1180                        # Optimization: In the case of primary-key lookups, we
1181                        # don't have to do an extra join.
1182                        if lookup_list and lookup_list[0] == f.rel.to.pk.name and lookup_type == 'exact':
1183                            where.append(_get_where_clause(lookup_type, rel_table_alias+'.',
1184                                f.rel.to.object_name.lower()+'_id', kwarg_value))
1185                            params.extend(f.get_db_prep_lookup(lookup_type, kwarg_value))
1186                            lookup_list.pop()
1187                            param_required = False
1188                        else:
1189                            new_table_alias = 't%s' % table_count
1190                            tables.append('%s %s' % (f.rel.to.db_table, new_table_alias))
1191                            join_where.append('%s.%s_id = %s.%s' % (rel_table_alias, f.rel.to.object_name.lower(),
1192                                new_table_alias, f.rel.to.pk.name))
1193                            current_table_alias = new_table_alias
1194                            param_required = True
1195                        current_opts = f.rel.to
1196                        raise StopIteration
1197                for f in current_opts.fields:
1198                    # Try many-to-one relationships...
1199                    if f.rel and f.rel.name == current:
1200                        # Optimization: In the case of primary-key lookups, we
1201                        # don't have to do an extra join.
1202                        if lookup_list and lookup_list[0] == f.rel.to.pk.name and lookup_type == 'exact':
1203                            where.append(_get_where_clause(lookup_type, current_table_alias+'.', f.name, kwarg_value))
1204                            params.extend(f.get_db_prep_lookup(lookup_type, kwarg_value))
1205                            lookup_list.pop()
1206                            param_required = False
1207                        else:
1208                            new_table_alias = 't%s' % table_count
1209                            tables.append('%s %s' % (f.rel.to.db_table, new_table_alias))
1210                            join_where.append('%s.%s = %s.%s' % (current_table_alias, f.name, new_table_alias, f.rel.to.pk.name))
1211                            current_table_alias = new_table_alias
1212                            param_required = True
1213                        current_opts = f.rel.to
1214                        raise StopIteration
1215                    # Try direct field-name lookups...
1216                    if f.name == current:
1217                        where.append(_get_where_clause(lookup_type, current_table_alias+'.', current, kwarg_value))
1218                        params.extend(f.get_db_prep_lookup(lookup_type, kwarg_value))
1219                        param_required = False
1220                        raise StopIteration
1221                # If we haven't hit StopIteration at this point, "current" must be
1222                # an invalid lookup, so raise an exception.
1223                _throw_bad_kwarg_error(kwarg)
1224            except StopIteration:
1225                continue
1226    return tables, join_where, where, params, table_count
1227
1228def function_get_sql_clause(opts, **kwargs):
1229    select = ["%s.%s" % (opts.db_table, f.name) for f in opts.fields]
1230    tables = [opts.db_table] + (kwargs.get('tables') and kwargs['tables'][:] or [])
1231    where = kwargs.get('where') and kwargs['where'][:] or []
1232    params = kwargs.get('params') and kwargs['params'][:] or []
1233
1234    # Convert the kwargs into SQL.
1235    tables2, join_where2, where2, params2, _ = _parse_lookup(kwargs.items(), opts)
1236    tables.extend(tables2)
1237    where.extend(join_where2 + where2)
1238    params.extend(params2)
1239
1240    # Add any additional constraints from the "where_constraints" parameter.
1241    where.extend(opts.where_constraints)
1242
1243    # Add additional tables and WHERE clauses based on select_related.
1244    if kwargs.get('select_related') is True:
1245        _fill_table_cache(opts, select, tables, where, opts.db_table, [opts.db_table])
1246
1247    # Add any additional SELECTs passed in via kwargs.
1248    if kwargs.get('select'):
1249        select.extend(['(%s) AS %s' % (s[1], s[0]) for s in kwargs['select']])
1250
1251    # ORDER BY clause
1252    order_by = []
1253    for f in handle_legacy_orderlist(kwargs.get('order_by', opts.ordering)):
1254        if f == '?': # Special case.
1255            order_by.append('RANDOM()')
1256        else:
1257            # Use the database table as a column prefix if it wasn't given,
1258            # and if the requested column isn't a custom SELECT.
1259            if "." not in f and f not in [k[0] for k in kwargs.get('select', [])]:
1260                table_prefix = opts.db_table + '.'
1261            else:
1262                table_prefix = ''
1263            if f.startswith('-'):
1264                order_by.append('%s%s DESC' % (table_prefix, f[1:]))
1265            else:
1266                order_by.append('%s%s ASC' % (table_prefix, f))
1267    order_by = ", ".join(order_by)
1268
1269
1270    sql = " FROM " + ",".join(tables) + (where and " WHERE " + " AND ".join(where) or "") + (order_by and " ORDER BY " + order_by or "")
1271
1272    if (db.DATABASE_ENGINE != 'oracle'):
1273        # LIMIT and OFFSET clauses
1274        if kwargs.get('limit') is not None:           
1275            limit_sql = " LIMIT %s " % kwargs['limit']
1276            if kwargs.get('offset') is not None and kwargs['offset'] != 0:
1277                limit_sql += "OFFSET %s " % kwargs['offset']
1278        else:
1279            limit_sql = ""       
1280
1281        full_query = "SELECT " + (kwargs.get('distinct') and "DISTINCT " or "") + ",".join(select) + sql + limit_sql
1282        return select, sql + limit_sql, params, full_query
1283    else:
1284        # To support limits and offsets, Oracle requires some funky rewriting of an otherwise normal looking query.
1285       
1286        select_clause = ",".join(select)
1287        distinct = (kwargs.get('distinct') and "DISTINCT " or "")
1288        from_clause = ",".join(tables)
1289        where_clause = (where and " WHERE " + " AND ".join(where) or "")
1290       
1291        if order_by:           
1292            order_by_clause = " OVER (ORDER BY %s )" % (order_by)
1293        else:
1294            #Oracle's row_number() function always requires an order-by clause.
1295            #So we need to define a default order-by, since none was provided.
1296            order_by_clause = " OVER (ORDER BY %s.%s)" % (opts.db_table, opts.fields[0].name)           
1297       
1298        # limit_and_offset_clause
1299        limit = kwargs.get('limit',0)
1300        offset = kwargs.get('offset',0)
1301       
1302        limit_and_offset_clause = ''
1303        if limit:
1304            limit = int(limit)
1305            offset = int(offset)
1306            limit_and_offset_clause = "WHERE rn > %s AND rn <= %s" % (offset, limit+offset)
1307        else:
1308            limit_and_offset_clause = "WHERE rn > %s" % (offset)
1309                                 
1310        full_query = """SELECT * FROM
1311                         (SELECT %s                 
1312                          %s,
1313                          ROW_NUMBER() %s AS rn
1314                          FROM %s
1315                          %s
1316                         )
1317                         %s
1318                     """ % (distinct, select_clause, order_by_clause, from_clause, where_clause, limit_and_offset_clause)
1319        return select, sql, params, full_query                               
1320
1321def function_get_in_bulk(opts, klass, *args, **kwargs):
1322    id_list = args and args[0] or kwargs['id_list']
1323    assert id_list != [], "get_in_bulk() cannot be passed an empty list."
1324    kwargs['where'] = ["%s.id IN (%s)" % (opts.db_table, ",".join(map(str, id_list)))]
1325    obj_list = function_get_list(opts, klass, **kwargs)
1326    return dict([(o.id, o) for o in obj_list])
1327
1328def function_get_latest(opts, klass, does_not_exist_exception, **kwargs):
1329    kwargs['order_by'] = ('-' + opts.get_latest_by,)
1330    kwargs['limit'] = 1
1331    return function_get_object(opts, klass, does_not_exist_exception, **kwargs)
1332
1333def function_get_date_list(opts, field, *args, **kwargs):
1334    from django.core.db.typecasts import typecast_timestamp
1335    kind = args and args[0] or kwargs['kind']
1336    assert kind in ("month", "year", "day"), "'kind' must be one of 'year', 'month' or 'day'."
1337    order = 'ASC'
1338    if kwargs.has_key('_order'):
1339        order = kwargs['_order']
1340        del kwargs['_order']
1341    assert order in ('ASC', 'DESC'), "'order' must be either 'ASC' or 'DESC'"
1342    kwargs['order_by'] = [] # Clear this because it'll mess things up otherwise.
1343    if field.null:
1344        kwargs.setdefault('where', []).append('%s.%s IS NOT NULL' % (opts.db_table, field.name))
1345    select, sql, params, full_query = function_get_sql_clause(opts, **kwargs)
1346    sql = 'SELECT %s %s GROUP BY 1 ORDER BY 1' % (db.get_date_trunc_sql(kind, '%s.%s' % (opts.db_table, field.name)), sql)
1347    cursor = db.db.cursor()
1348    cursor.execute(sql, params)
1349    # We have to manually run typecast_timestamp(str()) on the results, because
1350    # MySQL doesn't automatically cast the result of date functions as datetime
1351    # objects -- MySQL returns the values as strings, instead.
1352    return [typecast_timestamp(str(row[0])) for row in cursor.fetchall()]
1353
1354###################################
1355# HELPER FUNCTIONS (MANIPULATORS) #
1356###################################
1357
1358def get_manipulator(opts, klass, extra_methods, add=False, change=False):
1359    "Returns the custom Manipulator (either add or change) for the given opts."
1360    assert (add == False or change == False) and add != change, "get_manipulator() can be passed add=True or change=True, but not both"
1361    man = types.ClassType('%sManipulator%s' % (opts.object_name, add and 'Add' or 'Change'), (formfields.Manipulator,), {})
1362    man.__module__ = MODEL_PREFIX + '.' + opts.module_name # Set this explicitly, as above.
1363    man.__init__ = curry(manipulator_init, opts, add, change)
1364    man.save = curry(manipulator_save, opts, klass, add, change)
1365    for field_name_list in opts.unique_together:
1366        setattr(man, 'isUnique%s' % '_'.join(field_name_list), curry(manipulator_validator_unique_together, field_name_list, opts))
1367    for f in opts.fields:
1368        if f.unique_for_date:
1369            setattr(man, 'isUnique%sFor%s' % (f.name, f.unique_for_date), curry(manipulator_validator_unique_for_date, f, opts.get_field(f.unique_for_date), opts, 'date'))
1370        if f.unique_for_month:
1371            setattr(man, 'isUnique%sFor%s' % (f.name, f.unique_for_month), curry(manipulator_validator_unique_for_date, f, opts.get_field(f.unique_for_month), opts, 'month'))
1372        if f.unique_for_year:
1373            setattr(man, 'isUnique%sFor%s' % (f.name, f.unique_for_year), curry(manipulator_validator_unique_for_date, f, opts.get_field(f.unique_for_year), opts, 'year'))
1374    for k, v in extra_methods.items():
1375        setattr(man, k, v)
1376    return man
1377
1378def manipulator_init(opts, add, change, self, obj_key=None):
1379    if change:
1380        assert obj_key is not None, "ChangeManipulator.__init__() must be passed obj_key parameter."
1381        self.obj_key = obj_key
1382        try:
1383            self.original_object = opts.get_model_module().get_object(pk=obj_key)
1384        except ObjectDoesNotExist:
1385            # If the object doesn't exist, this might be a manipulator for a
1386            # one-to-one related object that hasn't created its subobject yet.
1387            # For example, this might be a Restaurant for a Place that doesn't
1388            # yet have restaurant information.
1389            if opts.one_to_one_field:
1390                # Sanity check -- Make sure the "parent" object exists.
1391                # For example, make sure the Place exists for the Restaurant.
1392                # Let the ObjectDoesNotExist exception propogate up.
1393                lookup_kwargs = opts.one_to_one_field.rel.limit_choices_to
1394                lookup_kwargs['%s__exact' % opts.one_to_one_field.rel.field_name] = obj_key
1395                _ = opts.one_to_one_field.rel.to.get_model_module().get_object(**lookup_kwargs)
1396                params = dict([(f.name, f.get_default()) for f in opts.fields])
1397                params[opts.pk.name] = obj_key
1398                self.original_object = opts.get_model_module().Klass(**params)
1399            else:
1400                raise
1401    self.fields = []
1402    for f in opts.fields + opts.many_to_many:
1403        if f.editable and not (f.primary_key and change) and (not f.rel or not f.rel.edit_inline):
1404            self.fields.extend(f.get_manipulator_fields(opts, self, change))
1405
1406    # Add fields for related objects.
1407    for rel_opts, rel_field in opts.get_inline_related_objects():
1408        if change:
1409            count = getattr(self.original_object, 'get_%s_count' % opts.get_rel_object_method_name(rel_opts, rel_field))()
1410            count += rel_field.rel.num_extra_on_change
1411            if rel_field.rel.min_num_in_admin:
1412                count = max(count, rel_field.rel.min_num_in_admin)
1413            if rel_field.rel.max_num_in_admin:
1414                count = min(count, rel_field.rel.max_num_in_admin)
1415        else:
1416            count = rel_field.rel.num_in_admin
1417        for f in rel_opts.fields + rel_opts.many_to_many:
1418            if f.editable and f != rel_field and (not f.primary_key or (f.primary_key and change)):
1419                for i in range(count):
1420                    self.fields.extend(f.get_manipulator_fields(rel_opts, self, change, name_prefix='%s.%d.' % (rel_opts.object_name.lower(), i), rel=True))
1421
1422    # Add field for ordering.
1423    if change and opts.get_ordered_objects():
1424        self.fields.append(formfields.CommaSeparatedIntegerField(field_name="order_"))
1425
1426def manipulator_save(opts, klass, add, change, self, new_data):
1427    from django.utils.datastructures import DotExpandedDict
1428    params = {}
1429    for f in opts.fields:
1430        # Fields with auto_now_add are another special case; they should keep
1431        # their original value in the change stage.
1432        if change and getattr(f, 'auto_now_add', False):
1433            params[f.name] = getattr(self.original_object, f.name)
1434        else:
1435            params[f.name] = f.get_manipulator_new_data(new_data)
1436
1437    if change:
1438        params[opts.pk.name] = self.obj_key
1439
1440    # First, save the basic object itself.
1441    new_object = klass(**params)
1442    new_object.save()
1443
1444    # Now that the object's been saved, save any uploaded files.
1445    for f in opts.fields:
1446        if isinstance(f, FileField):
1447            f.save_file(new_data, new_object, change and self.original_object or None, change, rel=False)
1448
1449    # Calculate which primary fields have changed.
1450    if change:
1451        self.fields_added, self.fields_changed, self.fields_deleted = [], [], []
1452        for f in opts.fields:
1453            if not f.primary_key and str(getattr(self.original_object, f.name)) != str(getattr(new_object, f.name)):
1454                self.fields_changed.append(f.verbose_name)
1455
1456    # Save many-to-many objects. Example: Poll.set_sites()
1457    for f in opts.many_to_many:
1458        if not f.rel.edit_inline:
1459            was_changed = getattr(new_object, 'set_%s' % f.name)(new_data.getlist(f.name))
1460            if change and was_changed:
1461                self.fields_changed.append(f.verbose_name)
1462
1463    # Save many-to-one objects. Example: Add the Choice objects for a Poll.
1464    for rel_opts, rel_field in opts.get_inline_related_objects():
1465        # Create obj_list, which is a DotExpandedDict such as this:
1466        # [('0', {'id': ['940'], 'choice': ['This is the first choice']}),
1467        #  ('1', {'id': ['941'], 'choice': ['This is the second choice']}),
1468        #  ('2', {'id': [''], 'choice': ['']})]
1469        obj_list = DotExpandedDict(new_data.data)[rel_opts.object_name.lower()].items()
1470        obj_list.sort(lambda x, y: cmp(int(x[0]), int(y[0])))
1471        params = {}
1472
1473        # For each related item...
1474        for _, rel_new_data in obj_list:
1475
1476            # Keep track of which core=True fields were provided.
1477            # If all core fields were given, the related object will be saved.
1478            # If none of the core fields were given, the object will be deleted.
1479            # If some, but not all, of the fields were given, the validator would
1480            # have caught that.
1481            all_cores_given, all_cores_blank = True, True
1482
1483            # Get a reference to the old object. We'll use it to compare the
1484            # old to the new, to see which fields have changed.
1485            if change:
1486                old_rel_obj = None
1487                if rel_new_data[rel_opts.pk.name][0]:
1488                    try:
1489                        old_rel_obj = getattr(self.original_object, 'get_%s' % opts.get_rel_object_method_name(rel_opts, rel_field))(**{'%s__exact' % rel_opts.pk.name: rel_new_data[rel_opts.pk.name][0]})
1490                    except ObjectDoesNotExist:
1491                        pass
1492
1493            for f in rel_opts.fields:
1494                if f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) in (None, ''):
1495                    all_cores_given = False
1496                elif f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) not in (None, ''):
1497                    all_cores_blank = False
1498                # If this field isn't editable, give it the same value it had
1499                # previously, according to the given ID. If the ID wasn't
1500                # given, use a default value. FileFields are also a special
1501                # case, because they'll be dealt with later.
1502                if change and (isinstance(f, FileField) or not f.editable):
1503                    if rel_new_data.get(rel_opts.pk.name, False) and rel_new_data[rel_opts.pk.name][0]:
1504                        params[f.name] = getattr(old_rel_obj, f.name)
1505                    else:
1506                        params[f.name] = f.get_default()
1507                elif f == rel_field:
1508                    params[f.name] = getattr(new_object, rel_field.rel.field_name)
1509                elif add and isinstance(f, AutoField):
1510                    params[f.name] = None
1511                else:
1512                    params[f.name] = f.get_manipulator_new_data(rel_new_data, rel=True)
1513                # Related links are a special case, because we have to
1514                # manually set the "content_type_id" field.
1515                if opts.has_related_links and rel_opts.module_name == 'relatedlinks':
1516                    contenttypes_mod = get_module('core', 'contenttypes')
1517                    params['content_type_id'] = contenttypes_mod.get_object(package__label__exact=opts.app_label, python_module_name__exact=opts.module_name).id
1518                    params['object_id'] = new_object.id
1519
1520            # Create the related item.
1521            new_rel_obj = rel_opts.get_model_module().Klass(**params)
1522
1523            # If all the core fields were provided (non-empty), save the item.
1524            if all_cores_given:
1525                new_rel_obj.save()
1526
1527                # Save any uploaded files.
1528                for f in rel_opts.fields:
1529                    if isinstance(f, FileField) and rel_new_data.get(f.name, False):
1530                        f.save_file(rel_new_data, new_rel_obj, change and old_rel_obj or None, change, rel=True)
1531
1532                # Calculate whether any fields have changed.
1533                if change:
1534                    if not old_rel_obj: # This object didn't exist before.
1535                        self.fields_added.append('%s "%r"' % (rel_opts.verbose_name, new_rel_obj))
1536                    else:
1537                        for f in rel_opts.fields:
1538                            if not f.primary_key and f != rel_field and str(getattr(old_rel_obj, f.name)) != str(getattr(new_rel_obj, f.name)):
1539                                self.fields_changed.append('%s for %s "%r"' % (f.verbose_name, rel_opts.verbose_name, new_rel_obj))
1540
1541                # Save many-to-many objects.
1542                for f in rel_opts.many_to_many:
1543                    if not f.rel.edit_inline:
1544                        was_changed = getattr(new_rel_obj, 'set_%s' % f.name)(rel_new_data[f.name])
1545                        if change and was_changed:
1546                            self.fields_changed.append('%s for %s "%s"' % (f.verbose_name, rel_opts.verbose_name, new_rel_obj))
1547
1548            # If, in the change stage, all of the core fields were blank and
1549            # the primary key (ID) was provided, delete the item.
1550            if change and all_cores_blank and rel_new_data.has_key(rel_opts.pk.name) and rel_new_data[rel_opts.pk.name][0]:
1551                new_rel_obj.delete()
1552                self.fields_deleted.append('%s "%r"' % (rel_opts.verbose_name, old_rel_obj))
1553
1554    # Save the order, if applicable.
1555    if change and opts.get_ordered_objects():
1556        order = new_data['order_'] and map(int, new_data['order_'].split(',')) or []
1557        for rel_opts in opts.get_ordered_objects():
1558            getattr(new_object, 'set_%s_order' % rel_opts.object_name.lower())(order)
1559    return new_object
1560
1561def manipulator_validator_unique_together(field_name_list, opts, self, field_data, all_data):
1562    from django.utils.text import get_text_list
1563    field_list = [opts.get_field(field_name) for field_name in field_name_list]
1564    kwargs = {'%s__iexact' % field_name_list[0]: field_data}
1565    for f in field_list[1:]:
1566        field_val = all_data.get(f.name, None)
1567        if field_val is None:
1568            # This will be caught by another validator, assuming the field
1569            # doesn't have blank=True.
1570            return
1571        kwargs['%s__iexact' % f.name] = field_val
1572    mod = opts.get_model_module()
1573    try:
1574        old_obj = mod.get_object(**kwargs)
1575    except ObjectDoesNotExist:
1576        return
1577    if hasattr(self, 'original_object') and getattr(self.original_object, opts.pk.name) == getattr(old_obj, opts.pk.name):
1578        pass
1579    else:
1580        raise validators.ValidationError, "%s with this %s already exists for the given %s." % \
1581            (capfirst(opts.verbose_name), field_list[0].verbose_name, get_text_list(field_name_list[1:], 'and'))
1582
1583def manipulator_validator_unique_for_date(from_field, date_field, opts, lookup_type, self, field_data, all_data):
1584    date_str = all_data.get(date_field.get_manipulator_field_names('')[0], None)
1585    mod = opts.get_model_module()
1586    date_val = formfields.DateField.html2python(date_str)
1587    if date_val is None:
1588        return # Date was invalid. This will be caught by another validator.
1589    lookup_kwargs = {'%s__iexact' % from_field.name: field_data, '%s__year' % date_field.name: date_val.year}
1590    if lookup_type in ('month', 'date'):
1591        lookup_kwargs['%s__month' % date_field.name] = date_val.month
1592    if lookup_type == 'date':
1593        lookup_kwargs['%s__day' % date_field.name] = date_val.day
1594    try:
1595        old_obj = mod.get_object(**lookup_kwargs)
1596    except ObjectDoesNotExist:
1597        return
1598    else:
1599        if hasattr(self, 'original_object') and getattr(self.original_object, opts.pk.name) == getattr(old_obj, opts.pk.name):
1600            pass
1601        else:
1602            format_string = (lookup_type == 'date') and '%B %d, %Y' or '%B %Y'
1603            raise validators.ValidationError, "Please enter a different %s. The one you entered is already being used for %s." % \
1604                (from_field.verbose_name, date_val.strftime(format_string))
Back to Top