web/lib/django/db/models/fields/related.py
changeset 38 77b6da96e6f1
equal deleted inserted replaced
37:8d941af65caf 38:77b6da96e6f1
       
     1 from django.conf import settings
       
     2 from django.db import connection, router, transaction
       
     3 from django.db.backends import util
       
     4 from django.db.models import signals, get_model
       
     5 from django.db.models.fields import (AutoField, Field, IntegerField,
       
     6     PositiveIntegerField, PositiveSmallIntegerField, FieldDoesNotExist)
       
     7 from django.db.models.related import RelatedObject
       
     8 from django.db.models.query import QuerySet
       
     9 from django.db.models.query_utils import QueryWrapper
       
    10 from django.utils.encoding import smart_unicode
       
    11 from django.utils.translation import ugettext_lazy as _, string_concat, ungettext, ugettext
       
    12 from django.utils.functional import curry
       
    13 from django.core import exceptions
       
    14 from django import forms
       
    15 
       
    16 
       
    17 RECURSIVE_RELATIONSHIP_CONSTANT = 'self'
       
    18 
       
    19 pending_lookups = {}
       
    20 
       
    21 def add_lazy_relation(cls, field, relation, operation):
       
    22     """
       
    23     Adds a lookup on ``cls`` when a related field is defined using a string,
       
    24     i.e.::
       
    25 
       
    26         class MyModel(Model):
       
    27             fk = ForeignKey("AnotherModel")
       
    28 
       
    29     This string can be:
       
    30 
       
    31         * RECURSIVE_RELATIONSHIP_CONSTANT (i.e. "self") to indicate a recursive
       
    32           relation.
       
    33 
       
    34         * The name of a model (i.e "AnotherModel") to indicate another model in
       
    35           the same app.
       
    36 
       
    37         * An app-label and model name (i.e. "someapp.AnotherModel") to indicate
       
    38           another model in a different app.
       
    39 
       
    40     If the other model hasn't yet been loaded -- almost a given if you're using
       
    41     lazy relationships -- then the relation won't be set up until the
       
    42     class_prepared signal fires at the end of model initialization.
       
    43 
       
    44     operation is the work that must be performed once the relation can be resolved.
       
    45     """
       
    46     # Check for recursive relations
       
    47     if relation == RECURSIVE_RELATIONSHIP_CONSTANT:
       
    48         app_label = cls._meta.app_label
       
    49         model_name = cls.__name__
       
    50 
       
    51     else:
       
    52         # Look for an "app.Model" relation
       
    53         try:
       
    54             app_label, model_name = relation.split(".")
       
    55         except ValueError:
       
    56             # If we can't split, assume a model in current app
       
    57             app_label = cls._meta.app_label
       
    58             model_name = relation
       
    59         except AttributeError:
       
    60             # If it doesn't have a split it's actually a model class
       
    61             app_label = relation._meta.app_label
       
    62             model_name = relation._meta.object_name
       
    63 
       
    64     # Try to look up the related model, and if it's already loaded resolve the
       
    65     # string right away. If get_model returns None, it means that the related
       
    66     # model isn't loaded yet, so we need to pend the relation until the class
       
    67     # is prepared.
       
    68     model = get_model(app_label, model_name, False)
       
    69     if model:
       
    70         operation(field, model, cls)
       
    71     else:
       
    72         key = (app_label, model_name)
       
    73         value = (cls, field, operation)
       
    74         pending_lookups.setdefault(key, []).append(value)
       
    75 
       
    76 def do_pending_lookups(sender, **kwargs):
       
    77     """
       
    78     Handle any pending relations to the sending model. Sent from class_prepared.
       
    79     """
       
    80     key = (sender._meta.app_label, sender.__name__)
       
    81     for cls, field, operation in pending_lookups.pop(key, []):
       
    82         operation(field, sender, cls)
       
    83 
       
    84 signals.class_prepared.connect(do_pending_lookups)
       
    85 
       
    86 #HACK
       
    87 class RelatedField(object):
       
    88     def contribute_to_class(self, cls, name):
       
    89         sup = super(RelatedField, self)
       
    90 
       
    91         # Store the opts for related_query_name()
       
    92         self.opts = cls._meta
       
    93 
       
    94         if hasattr(sup, 'contribute_to_class'):
       
    95             sup.contribute_to_class(cls, name)
       
    96 
       
    97         if not cls._meta.abstract and self.rel.related_name:
       
    98             self.rel.related_name = self.rel.related_name % {
       
    99                     'class': cls.__name__.lower(),
       
   100                     'app_label': cls._meta.app_label.lower(),
       
   101                 }
       
   102 
       
   103         other = self.rel.to
       
   104         if isinstance(other, basestring) or other._meta.pk is None:
       
   105             def resolve_related_class(field, model, cls):
       
   106                 field.rel.to = model
       
   107                 field.do_related_class(model, cls)
       
   108             add_lazy_relation(cls, self, other, resolve_related_class)
       
   109         else:
       
   110             self.do_related_class(other, cls)
       
   111 
       
   112     def set_attributes_from_rel(self):
       
   113         self.name = self.name or (self.rel.to._meta.object_name.lower() + '_' + self.rel.to._meta.pk.name)
       
   114         if self.verbose_name is None:
       
   115             self.verbose_name = self.rel.to._meta.verbose_name
       
   116         self.rel.field_name = self.rel.field_name or self.rel.to._meta.pk.name
       
   117 
       
   118     def do_related_class(self, other, cls):
       
   119         self.set_attributes_from_rel()
       
   120         self.related = RelatedObject(other, cls, self)
       
   121         if not cls._meta.abstract:
       
   122             self.contribute_to_related_class(other, self.related)
       
   123 
       
   124     def get_prep_lookup(self, lookup_type, value):
       
   125         if hasattr(value, 'prepare'):
       
   126             return value.prepare()
       
   127         if hasattr(value, '_prepare'):
       
   128             return value._prepare()
       
   129         # FIXME: lt and gt are explicitly allowed to make
       
   130         # get_(next/prev)_by_date work; other lookups are not allowed since that
       
   131         # gets messy pretty quick. This is a good candidate for some refactoring
       
   132         # in the future.
       
   133         if lookup_type in ['exact', 'gt', 'lt', 'gte', 'lte']:
       
   134             return self._pk_trace(value, 'get_prep_lookup', lookup_type)
       
   135         if lookup_type in ('range', 'in'):
       
   136             return [self._pk_trace(v, 'get_prep_lookup', lookup_type) for v in value]
       
   137         elif lookup_type == 'isnull':
       
   138             return []
       
   139         raise TypeError("Related Field has invalid lookup: %s" % lookup_type)
       
   140 
       
   141     def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False):
       
   142         if not prepared:
       
   143             value = self.get_prep_lookup(lookup_type, value)
       
   144         if hasattr(value, 'get_compiler'):
       
   145             value = value.get_compiler(connection=connection)
       
   146         if hasattr(value, 'as_sql') or hasattr(value, '_as_sql'):
       
   147             # If the value has a relabel_aliases method, it will need to
       
   148             # be invoked before the final SQL is evaluated
       
   149             if hasattr(value, 'relabel_aliases'):
       
   150                 return value
       
   151             if hasattr(value, 'as_sql'):
       
   152                 sql, params = value.as_sql()
       
   153             else:
       
   154                 sql, params = value._as_sql(connection=connection)
       
   155             return QueryWrapper(('(%s)' % sql), params)
       
   156 
       
   157         # FIXME: lt and gt are explicitly allowed to make
       
   158         # get_(next/prev)_by_date work; other lookups are not allowed since that
       
   159         # gets messy pretty quick. This is a good candidate for some refactoring
       
   160         # in the future.
       
   161         if lookup_type in ['exact', 'gt', 'lt', 'gte', 'lte']:
       
   162             return [self._pk_trace(value, 'get_db_prep_lookup', lookup_type,
       
   163                             connection=connection, prepared=prepared)]
       
   164         if lookup_type in ('range', 'in'):
       
   165             return [self._pk_trace(v, 'get_db_prep_lookup', lookup_type,
       
   166                             connection=connection, prepared=prepared)
       
   167                     for v in value]
       
   168         elif lookup_type == 'isnull':
       
   169             return []
       
   170         raise TypeError("Related Field has invalid lookup: %s" % lookup_type)
       
   171 
       
   172     def _pk_trace(self, value, prep_func, lookup_type, **kwargs):
       
   173         # Value may be a primary key, or an object held in a relation.
       
   174         # If it is an object, then we need to get the primary key value for
       
   175         # that object. In certain conditions (especially one-to-one relations),
       
   176         # the primary key may itself be an object - so we need to keep drilling
       
   177         # down until we hit a value that can be used for a comparison.
       
   178         v = value
       
   179         try:
       
   180             while True:
       
   181                 v = getattr(v, v._meta.pk.name)
       
   182         except AttributeError:
       
   183             pass
       
   184         except exceptions.ObjectDoesNotExist:
       
   185             v = None
       
   186 
       
   187         field = self
       
   188         while field.rel:
       
   189             if hasattr(field.rel, 'field_name'):
       
   190                 field = field.rel.to._meta.get_field(field.rel.field_name)
       
   191             else:
       
   192                 field = field.rel.to._meta.pk
       
   193 
       
   194         if lookup_type in ('range', 'in'):
       
   195             v = [v]
       
   196         v = getattr(field, prep_func)(lookup_type, v, **kwargs)
       
   197         if isinstance(v, list):
       
   198             v = v[0]
       
   199         return v
       
   200 
       
   201     def related_query_name(self):
       
   202         # This method defines the name that can be used to identify this
       
   203         # related object in a table-spanning query. It uses the lower-cased
       
   204         # object_name by default, but this can be overridden with the
       
   205         # "related_name" option.
       
   206         return self.rel.related_name or self.opts.object_name.lower()
       
   207 
       
   208 class SingleRelatedObjectDescriptor(object):
       
   209     # This class provides the functionality that makes the related-object
       
   210     # managers available as attributes on a model class, for fields that have
       
   211     # a single "remote" value, on the class pointed to by a related field.
       
   212     # In the example "place.restaurant", the restaurant attribute is a
       
   213     # SingleRelatedObjectDescriptor instance.
       
   214     def __init__(self, related):
       
   215         self.related = related
       
   216         self.cache_name = related.get_cache_name()
       
   217 
       
   218     def __get__(self, instance, instance_type=None):
       
   219         if instance is None:
       
   220             return self
       
   221         try:
       
   222             return getattr(instance, self.cache_name)
       
   223         except AttributeError:
       
   224             params = {'%s__pk' % self.related.field.name: instance._get_pk_val()}
       
   225             db = router.db_for_read(self.related.model, instance=instance)
       
   226             rel_obj = self.related.model._base_manager.using(db).get(**params)
       
   227             setattr(instance, self.cache_name, rel_obj)
       
   228             return rel_obj
       
   229 
       
   230     def __set__(self, instance, value):
       
   231         if instance is None:
       
   232             raise AttributeError("%s must be accessed via instance" % self.related.opts.object_name)
       
   233 
       
   234         # The similarity of the code below to the code in
       
   235         # ReverseSingleRelatedObjectDescriptor is annoying, but there's a bunch
       
   236         # of small differences that would make a common base class convoluted.
       
   237 
       
   238         # If null=True, we can assign null here, but otherwise the value needs
       
   239         # to be an instance of the related class.
       
   240         if value is None and self.related.field.null == False:
       
   241             raise ValueError('Cannot assign None: "%s.%s" does not allow null values.' %
       
   242                                 (instance._meta.object_name, self.related.get_accessor_name()))
       
   243         elif value is not None and not isinstance(value, self.related.model):
       
   244             raise ValueError('Cannot assign "%r": "%s.%s" must be a "%s" instance.' %
       
   245                                 (value, instance._meta.object_name,
       
   246                                  self.related.get_accessor_name(), self.related.opts.object_name))
       
   247         elif value is not None:
       
   248             if instance._state.db is None:
       
   249                 instance._state.db = router.db_for_write(instance.__class__, instance=value)
       
   250             elif value._state.db is None:
       
   251                 value._state.db = router.db_for_write(value.__class__, instance=instance)
       
   252             elif value._state.db is not None and instance._state.db is not None:
       
   253                 if not router.allow_relation(value, instance):
       
   254                     raise ValueError('Cannot assign "%r": instance is on database "%s", value is on database "%s"' %
       
   255                                         (value, instance._state.db, value._state.db))
       
   256 
       
   257         # Set the value of the related field to the value of the related object's related field
       
   258         setattr(value, self.related.field.attname, getattr(instance, self.related.field.rel.get_related_field().attname))
       
   259 
       
   260         # Since we already know what the related object is, seed the related
       
   261         # object caches now, too. This avoids another db hit if you get the
       
   262         # object you just set.
       
   263         setattr(instance, self.cache_name, value)
       
   264         setattr(value, self.related.field.get_cache_name(), instance)
       
   265 
       
   266 class ReverseSingleRelatedObjectDescriptor(object):
       
   267     # This class provides the functionality that makes the related-object
       
   268     # managers available as attributes on a model class, for fields that have
       
   269     # a single "remote" value, on the class that defines the related field.
       
   270     # In the example "choice.poll", the poll attribute is a
       
   271     # ReverseSingleRelatedObjectDescriptor instance.
       
   272     def __init__(self, field_with_rel):
       
   273         self.field = field_with_rel
       
   274 
       
   275     def __get__(self, instance, instance_type=None):
       
   276         if instance is None:
       
   277             return self
       
   278 
       
   279         cache_name = self.field.get_cache_name()
       
   280         try:
       
   281             return getattr(instance, cache_name)
       
   282         except AttributeError:
       
   283             val = getattr(instance, self.field.attname)
       
   284             if val is None:
       
   285                 # If NULL is an allowed value, return it.
       
   286                 if self.field.null:
       
   287                     return None
       
   288                 raise self.field.rel.to.DoesNotExist
       
   289             other_field = self.field.rel.get_related_field()
       
   290             if other_field.rel:
       
   291                 params = {'%s__pk' % self.field.rel.field_name: val}
       
   292             else:
       
   293                 params = {'%s__exact' % self.field.rel.field_name: val}
       
   294 
       
   295             # If the related manager indicates that it should be used for
       
   296             # related fields, respect that.
       
   297             rel_mgr = self.field.rel.to._default_manager
       
   298             db = router.db_for_read(self.field.rel.to, instance=instance)
       
   299             if getattr(rel_mgr, 'use_for_related_fields', False):
       
   300                 rel_obj = rel_mgr.using(db).get(**params)
       
   301             else:
       
   302                 rel_obj = QuerySet(self.field.rel.to).using(db).get(**params)
       
   303             setattr(instance, cache_name, rel_obj)
       
   304             return rel_obj
       
   305 
       
   306     def __set__(self, instance, value):
       
   307         if instance is None:
       
   308             raise AttributeError("%s must be accessed via instance" % self._field.name)
       
   309 
       
   310         # If null=True, we can assign null here, but otherwise the value needs
       
   311         # to be an instance of the related class.
       
   312         if value is None and self.field.null == False:
       
   313             raise ValueError('Cannot assign None: "%s.%s" does not allow null values.' %
       
   314                                 (instance._meta.object_name, self.field.name))
       
   315         elif value is not None and not isinstance(value, self.field.rel.to):
       
   316             raise ValueError('Cannot assign "%r": "%s.%s" must be a "%s" instance.' %
       
   317                                 (value, instance._meta.object_name,
       
   318                                  self.field.name, self.field.rel.to._meta.object_name))
       
   319         elif value is not None:
       
   320             if instance._state.db is None:
       
   321                 instance._state.db = router.db_for_write(instance.__class__, instance=value)
       
   322             elif value._state.db is None:
       
   323                 value._state.db = router.db_for_write(value.__class__, instance=instance)
       
   324             elif value._state.db is not None and instance._state.db is not None:
       
   325                 if not router.allow_relation(value, instance):
       
   326                     raise ValueError('Cannot assign "%r": instance is on database "%s", value is on database "%s"' %
       
   327                                         (value, instance._state.db, value._state.db))
       
   328 
       
   329         # If we're setting the value of a OneToOneField to None, we need to clear
       
   330         # out the cache on any old related object. Otherwise, deleting the
       
   331         # previously-related object will also cause this object to be deleted,
       
   332         # which is wrong.
       
   333         if value is None:
       
   334             # Look up the previously-related object, which may still be available
       
   335             # since we've not yet cleared out the related field.
       
   336             # Use the cache directly, instead of the accessor; if we haven't
       
   337             # populated the cache, then we don't care - we're only accessing
       
   338             # the object to invalidate the accessor cache, so there's no
       
   339             # need to populate the cache just to expire it again.
       
   340             related = getattr(instance, self.field.get_cache_name(), None)
       
   341 
       
   342             # If we've got an old related object, we need to clear out its
       
   343             # cache. This cache also might not exist if the related object
       
   344             # hasn't been accessed yet.
       
   345             if related:
       
   346                 cache_name = self.field.related.get_cache_name()
       
   347                 try:
       
   348                     delattr(related, cache_name)
       
   349                 except AttributeError:
       
   350                     pass
       
   351 
       
   352         # Set the value of the related field
       
   353         try:
       
   354             val = getattr(value, self.field.rel.get_related_field().attname)
       
   355         except AttributeError:
       
   356             val = None
       
   357         setattr(instance, self.field.attname, val)
       
   358 
       
   359         # Since we already know what the related object is, seed the related
       
   360         # object cache now, too. This avoids another db hit if you get the
       
   361         # object you just set.
       
   362         setattr(instance, self.field.get_cache_name(), value)
       
   363 
       
   364 class ForeignRelatedObjectsDescriptor(object):
       
   365     # This class provides the functionality that makes the related-object
       
   366     # managers available as attributes on a model class, for fields that have
       
   367     # multiple "remote" values and have a ForeignKey pointed at them by
       
   368     # some other model. In the example "poll.choice_set", the choice_set
       
   369     # attribute is a ForeignRelatedObjectsDescriptor instance.
       
   370     def __init__(self, related):
       
   371         self.related = related   # RelatedObject instance
       
   372 
       
   373     def __get__(self, instance, instance_type=None):
       
   374         if instance is None:
       
   375             return self
       
   376 
       
   377         return self.create_manager(instance,
       
   378                 self.related.model._default_manager.__class__)
       
   379 
       
   380     def __set__(self, instance, value):
       
   381         if instance is None:
       
   382             raise AttributeError("Manager must be accessed via instance")
       
   383 
       
   384         manager = self.__get__(instance)
       
   385         # If the foreign key can support nulls, then completely clear the related set.
       
   386         # Otherwise, just move the named objects into the set.
       
   387         if self.related.field.null:
       
   388             manager.clear()
       
   389         manager.add(*value)
       
   390 
       
   391     def delete_manager(self, instance):
       
   392         """
       
   393         Returns a queryset based on the related model's base manager (rather
       
   394         than the default manager, as returned by __get__). Used by
       
   395         Model.delete().
       
   396         """
       
   397         return self.create_manager(instance,
       
   398                 self.related.model._base_manager.__class__)
       
   399 
       
   400     def create_manager(self, instance, superclass):
       
   401         """
       
   402         Creates the managers used by other methods (__get__() and delete()).
       
   403         """
       
   404         rel_field = self.related.field
       
   405         rel_model = self.related.model
       
   406 
       
   407         class RelatedManager(superclass):
       
   408             def get_query_set(self):
       
   409                 db = self._db or router.db_for_read(rel_model, instance=instance)
       
   410                 return superclass.get_query_set(self).using(db).filter(**(self.core_filters))
       
   411 
       
   412             def add(self, *objs):
       
   413                 for obj in objs:
       
   414                     if not isinstance(obj, self.model):
       
   415                         raise TypeError("'%s' instance expected" % self.model._meta.object_name)
       
   416                     setattr(obj, rel_field.name, instance)
       
   417                     obj.save()
       
   418             add.alters_data = True
       
   419 
       
   420             def create(self, **kwargs):
       
   421                 kwargs.update({rel_field.name: instance})
       
   422                 db = router.db_for_write(rel_model, instance=instance)
       
   423                 return super(RelatedManager, self).using(db).create(**kwargs)
       
   424             create.alters_data = True
       
   425 
       
   426             def get_or_create(self, **kwargs):
       
   427                 # Update kwargs with the related object that this
       
   428                 # ForeignRelatedObjectsDescriptor knows about.
       
   429                 kwargs.update({rel_field.name: instance})
       
   430                 db = router.db_for_write(rel_model, instance=instance)
       
   431                 return super(RelatedManager, self).using(db).get_or_create(**kwargs)
       
   432             get_or_create.alters_data = True
       
   433 
       
   434             # remove() and clear() are only provided if the ForeignKey can have a value of null.
       
   435             if rel_field.null:
       
   436                 def remove(self, *objs):
       
   437                     val = getattr(instance, rel_field.rel.get_related_field().attname)
       
   438                     for obj in objs:
       
   439                         # Is obj actually part of this descriptor set?
       
   440                         if getattr(obj, rel_field.attname) == val:
       
   441                             setattr(obj, rel_field.name, None)
       
   442                             obj.save()
       
   443                         else:
       
   444                             raise rel_field.rel.to.DoesNotExist("%r is not related to %r." % (obj, instance))
       
   445                 remove.alters_data = True
       
   446 
       
   447                 def clear(self):
       
   448                     for obj in self.all():
       
   449                         setattr(obj, rel_field.name, None)
       
   450                         obj.save()
       
   451                 clear.alters_data = True
       
   452 
       
   453         manager = RelatedManager()
       
   454         attname = rel_field.rel.get_related_field().name
       
   455         manager.core_filters = {'%s__%s' % (rel_field.name, attname):
       
   456                 getattr(instance, attname)}
       
   457         manager.model = self.related.model
       
   458 
       
   459         return manager
       
   460 
       
   461 def create_many_related_manager(superclass, rel=False):
       
   462     """Creates a manager that subclasses 'superclass' (which is a Manager)
       
   463     and adds behavior for many-to-many related objects."""
       
   464     through = rel.through
       
   465     class ManyRelatedManager(superclass):
       
   466         def __init__(self, model=None, core_filters=None, instance=None, symmetrical=None,
       
   467                 join_table=None, source_field_name=None, target_field_name=None,
       
   468                 reverse=False):
       
   469             super(ManyRelatedManager, self).__init__()
       
   470             self.core_filters = core_filters
       
   471             self.model = model
       
   472             self.symmetrical = symmetrical
       
   473             self.instance = instance
       
   474             self.source_field_name = source_field_name
       
   475             self.target_field_name = target_field_name
       
   476             self.through = through
       
   477             self._pk_val = self.instance.pk
       
   478             self.reverse = reverse
       
   479             if self._pk_val is None:
       
   480                 raise ValueError("%r instance needs to have a primary key value before a many-to-many relationship can be used." % instance.__class__.__name__)
       
   481 
       
   482         def get_query_set(self):
       
   483             db = self._db or router.db_for_read(self.instance.__class__, instance=self.instance)
       
   484             return superclass.get_query_set(self).using(db)._next_is_sticky().filter(**(self.core_filters))
       
   485 
       
   486         # If the ManyToMany relation has an intermediary model,
       
   487         # the add and remove methods do not exist.
       
   488         if rel.through._meta.auto_created:
       
   489             def add(self, *objs):
       
   490                 self._add_items(self.source_field_name, self.target_field_name, *objs)
       
   491 
       
   492                 # If this is a symmetrical m2m relation to self, add the mirror entry in the m2m table
       
   493                 if self.symmetrical:
       
   494                     self._add_items(self.target_field_name, self.source_field_name, *objs)
       
   495             add.alters_data = True
       
   496 
       
   497             def remove(self, *objs):
       
   498                 self._remove_items(self.source_field_name, self.target_field_name, *objs)
       
   499 
       
   500                 # If this is a symmetrical m2m relation to self, remove the mirror entry in the m2m table
       
   501                 if self.symmetrical:
       
   502                     self._remove_items(self.target_field_name, self.source_field_name, *objs)
       
   503             remove.alters_data = True
       
   504 
       
   505         def clear(self):
       
   506             self._clear_items(self.source_field_name)
       
   507 
       
   508             # If this is a symmetrical m2m relation to self, clear the mirror entry in the m2m table
       
   509             if self.symmetrical:
       
   510                 self._clear_items(self.target_field_name)
       
   511         clear.alters_data = True
       
   512 
       
   513         def create(self, **kwargs):
       
   514             # This check needs to be done here, since we can't later remove this
       
   515             # from the method lookup table, as we do with add and remove.
       
   516             if not rel.through._meta.auto_created:
       
   517                 opts = through._meta
       
   518                 raise AttributeError("Cannot use create() on a ManyToManyField which specifies an intermediary model. Use %s.%s's Manager instead." % (opts.app_label, opts.object_name))
       
   519             db = router.db_for_write(self.instance.__class__, instance=self.instance)
       
   520             new_obj = super(ManyRelatedManager, self).using(db).create(**kwargs)
       
   521             self.add(new_obj)
       
   522             return new_obj
       
   523         create.alters_data = True
       
   524 
       
   525         def get_or_create(self, **kwargs):
       
   526             db = router.db_for_write(self.instance.__class__, instance=self.instance)
       
   527             obj, created = \
       
   528                 super(ManyRelatedManager, self).using(db).get_or_create(**kwargs)
       
   529             # We only need to add() if created because if we got an object back
       
   530             # from get() then the relationship already exists.
       
   531             if created:
       
   532                 self.add(obj)
       
   533             return obj, created
       
   534         get_or_create.alters_data = True
       
   535 
       
   536         def _add_items(self, source_field_name, target_field_name, *objs):
       
   537             # join_table: name of the m2m link table
       
   538             # source_field_name: the PK fieldname in join_table for the source object
       
   539             # target_field_name: the PK fieldname in join_table for the target object
       
   540             # *objs - objects to add. Either object instances, or primary keys of object instances.
       
   541 
       
   542             # If there aren't any objects, there is nothing to do.
       
   543             from django.db.models import Model
       
   544             if objs:
       
   545                 new_ids = set()
       
   546                 for obj in objs:
       
   547                     if isinstance(obj, self.model):
       
   548                         if not router.allow_relation(obj, self.instance):
       
   549                            raise ValueError('Cannot add "%r": instance is on database "%s", value is on database "%s"' %
       
   550                                                (obj, self.instance._state.db, obj._state.db))
       
   551                         new_ids.add(obj.pk)
       
   552                     elif isinstance(obj, Model):
       
   553                         raise TypeError("'%s' instance expected" % self.model._meta.object_name)
       
   554                     else:
       
   555                         new_ids.add(obj)
       
   556                 db = router.db_for_write(self.through.__class__, instance=self.instance)
       
   557                 vals = self.through._default_manager.using(db).values_list(target_field_name, flat=True)
       
   558                 vals = vals.filter(**{
       
   559                     source_field_name: self._pk_val,
       
   560                     '%s__in' % target_field_name: new_ids,
       
   561                 })
       
   562                 new_ids = new_ids - set(vals)
       
   563 
       
   564                 if self.reverse or source_field_name == self.source_field_name:
       
   565                     # Don't send the signal when we are inserting the
       
   566                     # duplicate data row for symmetrical reverse entries.
       
   567                     signals.m2m_changed.send(sender=rel.through, action='pre_add',
       
   568                         instance=self.instance, reverse=self.reverse,
       
   569                         model=self.model, pk_set=new_ids)
       
   570                 # Add the ones that aren't there already
       
   571                 for obj_id in new_ids:
       
   572                     self.through._default_manager.using(db).create(**{
       
   573                         '%s_id' % source_field_name: self._pk_val,
       
   574                         '%s_id' % target_field_name: obj_id,
       
   575                     })
       
   576                 if self.reverse or source_field_name == self.source_field_name:
       
   577                     # Don't send the signal when we are inserting the
       
   578                     # duplicate data row for symmetrical reverse entries.
       
   579                     signals.m2m_changed.send(sender=rel.through, action='post_add',
       
   580                         instance=self.instance, reverse=self.reverse,
       
   581                         model=self.model, pk_set=new_ids)
       
   582 
       
   583         def _remove_items(self, source_field_name, target_field_name, *objs):
       
   584             # source_col_name: the PK colname in join_table for the source object
       
   585             # target_col_name: the PK colname in join_table for the target object
       
   586             # *objs - objects to remove
       
   587 
       
   588             # If there aren't any objects, there is nothing to do.
       
   589             if objs:
       
   590                 # Check that all the objects are of the right type
       
   591                 old_ids = set()
       
   592                 for obj in objs:
       
   593                     if isinstance(obj, self.model):
       
   594                         old_ids.add(obj.pk)
       
   595                     else:
       
   596                         old_ids.add(obj)
       
   597                 if self.reverse or source_field_name == self.source_field_name:
       
   598                     # Don't send the signal when we are deleting the
       
   599                     # duplicate data row for symmetrical reverse entries.
       
   600                     signals.m2m_changed.send(sender=rel.through, action="pre_remove",
       
   601                         instance=self.instance, reverse=self.reverse,
       
   602                         model=self.model, pk_set=old_ids)
       
   603                 # Remove the specified objects from the join table
       
   604                 db = router.db_for_write(self.through.__class__, instance=self.instance)
       
   605                 self.through._default_manager.using(db).filter(**{
       
   606                     source_field_name: self._pk_val,
       
   607                     '%s__in' % target_field_name: old_ids
       
   608                 }).delete()
       
   609                 if self.reverse or source_field_name == self.source_field_name:
       
   610                     # Don't send the signal when we are deleting the
       
   611                     # duplicate data row for symmetrical reverse entries.
       
   612                     signals.m2m_changed.send(sender=rel.through, action="post_remove",
       
   613                         instance=self.instance, reverse=self.reverse,
       
   614                         model=self.model, pk_set=old_ids)
       
   615 
       
   616         def _clear_items(self, source_field_name):
       
   617             # source_col_name: the PK colname in join_table for the source object
       
   618             if self.reverse or source_field_name == self.source_field_name:
       
   619                 # Don't send the signal when we are clearing the
       
   620                 # duplicate data rows for symmetrical reverse entries.
       
   621                 signals.m2m_changed.send(sender=rel.through, action="pre_clear",
       
   622                     instance=self.instance, reverse=self.reverse,
       
   623                     model=self.model, pk_set=None)
       
   624             db = router.db_for_write(self.through.__class__, instance=self.instance)
       
   625             self.through._default_manager.using(db).filter(**{
       
   626                 source_field_name: self._pk_val
       
   627             }).delete()
       
   628             if self.reverse or source_field_name == self.source_field_name:
       
   629                 # Don't send the signal when we are clearing the
       
   630                 # duplicate data rows for symmetrical reverse entries.
       
   631                 signals.m2m_changed.send(sender=rel.through, action="post_clear",
       
   632                     instance=self.instance, reverse=self.reverse,
       
   633                     model=self.model, pk_set=None)
       
   634 
       
   635     return ManyRelatedManager
       
   636 
       
   637 class ManyRelatedObjectsDescriptor(object):
       
   638     # This class provides the functionality that makes the related-object
       
   639     # managers available as attributes on a model class, for fields that have
       
   640     # multiple "remote" values and have a ManyToManyField pointed at them by
       
   641     # some other model (rather than having a ManyToManyField themselves).
       
   642     # In the example "publication.article_set", the article_set attribute is a
       
   643     # ManyRelatedObjectsDescriptor instance.
       
   644     def __init__(self, related):
       
   645         self.related = related   # RelatedObject instance
       
   646 
       
   647     def __get__(self, instance, instance_type=None):
       
   648         if instance is None:
       
   649             return self
       
   650 
       
   651         # Dynamically create a class that subclasses the related
       
   652         # model's default manager.
       
   653         rel_model = self.related.model
       
   654         superclass = rel_model._default_manager.__class__
       
   655         RelatedManager = create_many_related_manager(superclass, self.related.field.rel)
       
   656 
       
   657         manager = RelatedManager(
       
   658             model=rel_model,
       
   659             core_filters={'%s__pk' % self.related.field.name: instance._get_pk_val()},
       
   660             instance=instance,
       
   661             symmetrical=False,
       
   662             source_field_name=self.related.field.m2m_reverse_field_name(),
       
   663             target_field_name=self.related.field.m2m_field_name(),
       
   664             reverse=True
       
   665         )
       
   666 
       
   667         return manager
       
   668 
       
   669     def __set__(self, instance, value):
       
   670         if instance is None:
       
   671             raise AttributeError("Manager must be accessed via instance")
       
   672 
       
   673         if not self.related.field.rel.through._meta.auto_created:
       
   674             opts = self.related.field.rel.through._meta
       
   675             raise AttributeError("Cannot set values on a ManyToManyField which specifies an intermediary model. Use %s.%s's Manager instead." % (opts.app_label, opts.object_name))
       
   676 
       
   677         manager = self.__get__(instance)
       
   678         manager.clear()
       
   679         manager.add(*value)
       
   680 
       
   681 
       
   682 class ReverseManyRelatedObjectsDescriptor(object):
       
   683     # This class provides the functionality that makes the related-object
       
   684     # managers available as attributes on a model class, for fields that have
       
   685     # multiple "remote" values and have a ManyToManyField defined in their
       
   686     # model (rather than having another model pointed *at* them).
       
   687     # In the example "article.publications", the publications attribute is a
       
   688     # ReverseManyRelatedObjectsDescriptor instance.
       
   689     def __init__(self, m2m_field):
       
   690         self.field = m2m_field
       
   691 
       
   692     def _through(self):
       
   693         # through is provided so that you have easy access to the through
       
   694         # model (Book.authors.through) for inlines, etc. This is done as
       
   695         # a property to ensure that the fully resolved value is returned.
       
   696         return self.field.rel.through
       
   697     through = property(_through)
       
   698 
       
   699     def __get__(self, instance, instance_type=None):
       
   700         if instance is None:
       
   701             return self
       
   702 
       
   703         # Dynamically create a class that subclasses the related
       
   704         # model's default manager.
       
   705         rel_model=self.field.rel.to
       
   706         superclass = rel_model._default_manager.__class__
       
   707         RelatedManager = create_many_related_manager(superclass, self.field.rel)
       
   708 
       
   709         manager = RelatedManager(
       
   710             model=rel_model,
       
   711             core_filters={'%s__pk' % self.field.related_query_name(): instance._get_pk_val()},
       
   712             instance=instance,
       
   713             symmetrical=self.field.rel.symmetrical,
       
   714             source_field_name=self.field.m2m_field_name(),
       
   715             target_field_name=self.field.m2m_reverse_field_name(),
       
   716             reverse=False
       
   717         )
       
   718 
       
   719         return manager
       
   720 
       
   721     def __set__(self, instance, value):
       
   722         if instance is None:
       
   723             raise AttributeError("Manager must be accessed via instance")
       
   724 
       
   725         if not self.field.rel.through._meta.auto_created:
       
   726             opts = self.field.rel.through._meta
       
   727             raise AttributeError("Cannot set values on a ManyToManyField which specifies an intermediary model.  Use %s.%s's Manager instead." % (opts.app_label, opts.object_name))
       
   728 
       
   729         manager = self.__get__(instance)
       
   730         manager.clear()
       
   731         manager.add(*value)
       
   732 
       
   733 class ManyToOneRel(object):
       
   734     def __init__(self, to, field_name, related_name=None,
       
   735             limit_choices_to=None, lookup_overrides=None, parent_link=False):
       
   736         try:
       
   737             to._meta
       
   738         except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
       
   739             assert isinstance(to, basestring), "'to' must be either a model, a model name or the string %r" % RECURSIVE_RELATIONSHIP_CONSTANT
       
   740         self.to, self.field_name = to, field_name
       
   741         self.related_name = related_name
       
   742         if limit_choices_to is None:
       
   743             limit_choices_to = {}
       
   744         self.limit_choices_to = limit_choices_to
       
   745         self.lookup_overrides = lookup_overrides or {}
       
   746         self.multiple = True
       
   747         self.parent_link = parent_link
       
   748 
       
   749     def is_hidden(self):
       
   750         "Should the related object be hidden?"
       
   751         return self.related_name and self.related_name[-1] == '+'
       
   752 
       
   753     def get_related_field(self):
       
   754         """
       
   755         Returns the Field in the 'to' object to which this relationship is
       
   756         tied.
       
   757         """
       
   758         data = self.to._meta.get_field_by_name(self.field_name)
       
   759         if not data[2]:
       
   760             raise FieldDoesNotExist("No related field named '%s'" %
       
   761                     self.field_name)
       
   762         return data[0]
       
   763 
       
   764 class OneToOneRel(ManyToOneRel):
       
   765     def __init__(self, to, field_name, related_name=None,
       
   766             limit_choices_to=None, lookup_overrides=None, parent_link=False):
       
   767         super(OneToOneRel, self).__init__(to, field_name,
       
   768                 related_name=related_name, limit_choices_to=limit_choices_to,
       
   769                 lookup_overrides=lookup_overrides, parent_link=parent_link)
       
   770         self.multiple = False
       
   771 
       
   772 class ManyToManyRel(object):
       
   773     def __init__(self, to, related_name=None, limit_choices_to=None,
       
   774             symmetrical=True, through=None):
       
   775         self.to = to
       
   776         self.related_name = related_name
       
   777         if limit_choices_to is None:
       
   778             limit_choices_to = {}
       
   779         self.limit_choices_to = limit_choices_to
       
   780         self.symmetrical = symmetrical
       
   781         self.multiple = True
       
   782         self.through = through
       
   783 
       
   784     def is_hidden(self):
       
   785         "Should the related object be hidden?"
       
   786         return self.related_name and self.related_name[-1] == '+'
       
   787 
       
   788     def get_related_field(self):
       
   789         """
       
   790         Returns the field in the to' object to which this relationship is tied
       
   791         (this is always the primary key on the target model). Provided for
       
   792         symmetry with ManyToOneRel.
       
   793         """
       
   794         return self.to._meta.pk
       
   795 
       
   796 class ForeignKey(RelatedField, Field):
       
   797     empty_strings_allowed = False
       
   798     default_error_messages = {
       
   799         'invalid': _('Model %(model)s with pk %(pk)r does not exist.')
       
   800     }
       
   801     description = _("Foreign Key (type determined by related field)")
       
   802     def __init__(self, to, to_field=None, rel_class=ManyToOneRel, **kwargs):
       
   803         try:
       
   804             to_name = to._meta.object_name.lower()
       
   805         except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
       
   806             assert isinstance(to, basestring), "%s(%r) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT)
       
   807         else:
       
   808             assert not to._meta.abstract, "%s cannot define a relation with abstract class %s" % (self.__class__.__name__, to._meta.object_name)
       
   809             # For backwards compatibility purposes, we need to *try* and set
       
   810             # the to_field during FK construction. It won't be guaranteed to
       
   811             # be correct until contribute_to_class is called. Refs #12190.
       
   812             to_field = to_field or (to._meta.pk and to._meta.pk.name)
       
   813         kwargs['verbose_name'] = kwargs.get('verbose_name', None)
       
   814 
       
   815         kwargs['rel'] = rel_class(to, to_field,
       
   816             related_name=kwargs.pop('related_name', None),
       
   817             limit_choices_to=kwargs.pop('limit_choices_to', None),
       
   818             lookup_overrides=kwargs.pop('lookup_overrides', None),
       
   819             parent_link=kwargs.pop('parent_link', False))
       
   820         Field.__init__(self, **kwargs)
       
   821 
       
   822         self.db_index = True
       
   823 
       
   824     def validate(self, value, model_instance):
       
   825         if self.rel.parent_link:
       
   826             return
       
   827         super(ForeignKey, self).validate(value, model_instance)
       
   828         if value is None:
       
   829             return
       
   830 
       
   831         qs = self.rel.to._default_manager.filter(**{self.rel.field_name:value})
       
   832         qs = qs.complex_filter(self.rel.limit_choices_to)
       
   833         if not qs.exists():
       
   834             raise exceptions.ValidationError(self.error_messages['invalid'] % {
       
   835                 'model': self.rel.to._meta.verbose_name, 'pk': value})
       
   836 
       
   837     def get_attname(self):
       
   838         return '%s_id' % self.name
       
   839 
       
   840     def get_validator_unique_lookup_type(self):
       
   841         return '%s__%s__exact' % (self.name, self.rel.get_related_field().name)
       
   842 
       
   843     def get_default(self):
       
   844         "Here we check if the default value is an object and return the to_field if so."
       
   845         field_default = super(ForeignKey, self).get_default()
       
   846         if isinstance(field_default, self.rel.to):
       
   847             return getattr(field_default, self.rel.get_related_field().attname)
       
   848         return field_default
       
   849 
       
   850     def get_db_prep_save(self, value, connection):
       
   851         if value == '' or value == None:
       
   852             return None
       
   853         else:
       
   854             return self.rel.get_related_field().get_db_prep_save(value,
       
   855                 connection=connection)
       
   856 
       
   857     def value_to_string(self, obj):
       
   858         if not obj:
       
   859             # In required many-to-one fields with only one available choice,
       
   860             # select that one available choice. Note: For SelectFields
       
   861             # we have to check that the length of choices is *2*, not 1,
       
   862             # because SelectFields always have an initial "blank" value.
       
   863             if not self.blank and self.choices:
       
   864                 choice_list = self.get_choices_default()
       
   865                 if len(choice_list) == 2:
       
   866                     return smart_unicode(choice_list[1][0])
       
   867         return Field.value_to_string(self, obj)
       
   868 
       
   869     def contribute_to_class(self, cls, name):
       
   870         super(ForeignKey, self).contribute_to_class(cls, name)
       
   871         setattr(cls, self.name, ReverseSingleRelatedObjectDescriptor(self))
       
   872         if isinstance(self.rel.to, basestring):
       
   873             target = self.rel.to
       
   874         else:
       
   875             target = self.rel.to._meta.db_table
       
   876         cls._meta.duplicate_targets[self.column] = (target, "o2m")
       
   877 
       
   878     def contribute_to_related_class(self, cls, related):
       
   879         # Internal FK's - i.e., those with a related name ending with '+' -
       
   880         # don't get a related descriptor.
       
   881         if not self.rel.is_hidden():
       
   882             setattr(cls, related.get_accessor_name(), ForeignRelatedObjectsDescriptor(related))
       
   883         if self.rel.field_name is None:
       
   884             self.rel.field_name = cls._meta.pk.name
       
   885 
       
   886     def formfield(self, **kwargs):
       
   887         db = kwargs.pop('using', None)
       
   888         defaults = {
       
   889             'form_class': forms.ModelChoiceField,
       
   890             'queryset': self.rel.to._default_manager.using(db).complex_filter(self.rel.limit_choices_to),
       
   891             'to_field_name': self.rel.field_name,
       
   892         }
       
   893         defaults.update(kwargs)
       
   894         return super(ForeignKey, self).formfield(**defaults)
       
   895 
       
   896     def db_type(self, connection):
       
   897         # The database column type of a ForeignKey is the column type
       
   898         # of the field to which it points. An exception is if the ForeignKey
       
   899         # points to an AutoField/PositiveIntegerField/PositiveSmallIntegerField,
       
   900         # in which case the column type is simply that of an IntegerField.
       
   901         # If the database needs similar types for key fields however, the only
       
   902         # thing we can do is making AutoField an IntegerField.
       
   903         rel_field = self.rel.get_related_field()
       
   904         if (isinstance(rel_field, AutoField) or
       
   905                 (not connection.features.related_fields_match_type and
       
   906                 isinstance(rel_field, (PositiveIntegerField,
       
   907                                        PositiveSmallIntegerField)))):
       
   908             return IntegerField().db_type(connection=connection)
       
   909         return rel_field.db_type(connection=connection)
       
   910 
       
   911 class OneToOneField(ForeignKey):
       
   912     """
       
   913     A OneToOneField is essentially the same as a ForeignKey, with the exception
       
   914     that always carries a "unique" constraint with it and the reverse relation
       
   915     always returns the object pointed to (since there will only ever be one),
       
   916     rather than returning a list.
       
   917     """
       
   918     description = _("One-to-one relationship")
       
   919     def __init__(self, to, to_field=None, **kwargs):
       
   920         kwargs['unique'] = True
       
   921         super(OneToOneField, self).__init__(to, to_field, OneToOneRel, **kwargs)
       
   922 
       
   923     def contribute_to_related_class(self, cls, related):
       
   924         setattr(cls, related.get_accessor_name(),
       
   925                 SingleRelatedObjectDescriptor(related))
       
   926 
       
   927     def formfield(self, **kwargs):
       
   928         if self.rel.parent_link:
       
   929             return None
       
   930         return super(OneToOneField, self).formfield(**kwargs)
       
   931 
       
   932     def save_form_data(self, instance, data):
       
   933         if isinstance(data, self.rel.to):
       
   934             setattr(instance, self.name, data)
       
   935         else:
       
   936             setattr(instance, self.attname, data)
       
   937 
       
   938 def create_many_to_many_intermediary_model(field, klass):
       
   939     from django.db import models
       
   940     managed = True
       
   941     if isinstance(field.rel.to, basestring) and field.rel.to != RECURSIVE_RELATIONSHIP_CONSTANT:
       
   942         to_model = field.rel.to
       
   943         to = to_model.split('.')[-1]
       
   944         def set_managed(field, model, cls):
       
   945             field.rel.through._meta.managed = model._meta.managed or cls._meta.managed
       
   946         add_lazy_relation(klass, field, to_model, set_managed)
       
   947     elif isinstance(field.rel.to, basestring):
       
   948         to = klass._meta.object_name
       
   949         to_model = klass
       
   950         managed = klass._meta.managed
       
   951     else:
       
   952         to = field.rel.to._meta.object_name
       
   953         to_model = field.rel.to
       
   954         managed = klass._meta.managed or to_model._meta.managed
       
   955     name = '%s_%s' % (klass._meta.object_name, field.name)
       
   956     if field.rel.to == RECURSIVE_RELATIONSHIP_CONSTANT or to == klass._meta.object_name:
       
   957         from_ = 'from_%s' % to.lower()
       
   958         to = 'to_%s' % to.lower()
       
   959     else:
       
   960         from_ = klass._meta.object_name.lower()
       
   961         to = to.lower()
       
   962     meta = type('Meta', (object,), {
       
   963         'db_table': field._get_m2m_db_table(klass._meta),
       
   964         'managed': managed,
       
   965         'auto_created': klass,
       
   966         'app_label': klass._meta.app_label,
       
   967         'unique_together': (from_, to),
       
   968         'verbose_name': '%(from)s-%(to)s relationship' % {'from': from_, 'to': to},
       
   969         'verbose_name_plural': '%(from)s-%(to)s relationships' % {'from': from_, 'to': to},
       
   970     })
       
   971     # Construct and return the new class.
       
   972     return type(name, (models.Model,), {
       
   973         'Meta': meta,
       
   974         '__module__': klass.__module__,
       
   975         from_: models.ForeignKey(klass, related_name='%s+' % name),
       
   976         to: models.ForeignKey(to_model, related_name='%s+' % name)
       
   977     })
       
   978 
       
   979 class ManyToManyField(RelatedField, Field):
       
   980     description = _("Many-to-many relationship")
       
   981     def __init__(self, to, **kwargs):
       
   982         try:
       
   983             assert not to._meta.abstract, "%s cannot define a relation with abstract class %s" % (self.__class__.__name__, to._meta.object_name)
       
   984         except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
       
   985             assert isinstance(to, basestring), "%s(%r) is invalid. First parameter to ManyToManyField must be either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT)
       
   986 
       
   987         kwargs['verbose_name'] = kwargs.get('verbose_name', None)
       
   988         kwargs['rel'] = ManyToManyRel(to,
       
   989             related_name=kwargs.pop('related_name', None),
       
   990             limit_choices_to=kwargs.pop('limit_choices_to', None),
       
   991             symmetrical=kwargs.pop('symmetrical', to==RECURSIVE_RELATIONSHIP_CONSTANT),
       
   992             through=kwargs.pop('through', None))
       
   993 
       
   994         self.db_table = kwargs.pop('db_table', None)
       
   995         if kwargs['rel'].through is not None:
       
   996             assert self.db_table is None, "Cannot specify a db_table if an intermediary model is used."
       
   997 
       
   998         Field.__init__(self, **kwargs)
       
   999 
       
  1000         msg = _('Hold down "Control", or "Command" on a Mac, to select more than one.')
       
  1001         self.help_text = string_concat(self.help_text, ' ', msg)
       
  1002 
       
  1003     def get_choices_default(self):
       
  1004         return Field.get_choices(self, include_blank=False)
       
  1005 
       
  1006     def _get_m2m_db_table(self, opts):
       
  1007         "Function that can be curried to provide the m2m table name for this relation"
       
  1008         if self.rel.through is not None:
       
  1009             return self.rel.through._meta.db_table
       
  1010         elif self.db_table:
       
  1011             return self.db_table
       
  1012         else:
       
  1013             return util.truncate_name('%s_%s' % (opts.db_table, self.name),
       
  1014                                       connection.ops.max_name_length())
       
  1015 
       
  1016     def _get_m2m_attr(self, related, attr):
       
  1017         "Function that can be curried to provide the source accessor or DB column name for the m2m table"
       
  1018         cache_attr = '_m2m_%s_cache' % attr
       
  1019         if hasattr(self, cache_attr):
       
  1020             return getattr(self, cache_attr)
       
  1021         for f in self.rel.through._meta.fields:
       
  1022             if hasattr(f,'rel') and f.rel and f.rel.to == related.model:
       
  1023                 setattr(self, cache_attr, getattr(f, attr))
       
  1024                 return getattr(self, cache_attr)
       
  1025 
       
  1026     def _get_m2m_reverse_attr(self, related, attr):
       
  1027         "Function that can be curried to provide the related accessor or DB column name for the m2m table"
       
  1028         cache_attr = '_m2m_reverse_%s_cache' % attr
       
  1029         if hasattr(self, cache_attr):
       
  1030             return getattr(self, cache_attr)
       
  1031         found = False
       
  1032         for f in self.rel.through._meta.fields:
       
  1033             if hasattr(f,'rel') and f.rel and f.rel.to == related.parent_model:
       
  1034                 if related.model == related.parent_model:
       
  1035                     # If this is an m2m-intermediate to self,
       
  1036                     # the first foreign key you find will be
       
  1037                     # the source column. Keep searching for
       
  1038                     # the second foreign key.
       
  1039                     if found:
       
  1040                         setattr(self, cache_attr, getattr(f, attr))
       
  1041                         break
       
  1042                     else:
       
  1043                         found = True
       
  1044                 else:
       
  1045                     setattr(self, cache_attr, getattr(f, attr))
       
  1046                     break
       
  1047         return getattr(self, cache_attr)
       
  1048 
       
  1049     def isValidIDList(self, field_data, all_data):
       
  1050         "Validates that the value is a valid list of foreign keys"
       
  1051         mod = self.rel.to
       
  1052         try:
       
  1053             pks = map(int, field_data.split(','))
       
  1054         except ValueError:
       
  1055             # the CommaSeparatedIntegerField validator will catch this error
       
  1056             return
       
  1057         objects = mod._default_manager.in_bulk(pks)
       
  1058         if len(objects) != len(pks):
       
  1059             badkeys = [k for k in pks if k not in objects]
       
  1060             raise exceptions.ValidationError(
       
  1061                 ungettext("Please enter valid %(self)s IDs. The value %(value)r is invalid.",
       
  1062                           "Please enter valid %(self)s IDs. The values %(value)r are invalid.",
       
  1063                           len(badkeys)) % {
       
  1064                 'self': self.verbose_name,
       
  1065                 'value': len(badkeys) == 1 and badkeys[0] or tuple(badkeys),
       
  1066             })
       
  1067 
       
  1068     def value_to_string(self, obj):
       
  1069         data = ''
       
  1070         if obj:
       
  1071             qs = getattr(obj, self.name).all()
       
  1072             data = [instance._get_pk_val() for instance in qs]
       
  1073         else:
       
  1074             # In required many-to-many fields with only one available choice,
       
  1075             # select that one available choice.
       
  1076             if not self.blank:
       
  1077                 choices_list = self.get_choices_default()
       
  1078                 if len(choices_list) == 1:
       
  1079                     data = [choices_list[0][0]]
       
  1080         return smart_unicode(data)
       
  1081 
       
  1082     def contribute_to_class(self, cls, name):
       
  1083         # To support multiple relations to self, it's useful to have a non-None
       
  1084         # related name on symmetrical relations for internal reasons. The
       
  1085         # concept doesn't make a lot of sense externally ("you want me to
       
  1086         # specify *what* on my non-reversible relation?!"), so we set it up
       
  1087         # automatically. The funky name reduces the chance of an accidental
       
  1088         # clash.
       
  1089         if self.rel.symmetrical and (self.rel.to == "self" or self.rel.to == cls._meta.object_name):
       
  1090             self.rel.related_name = "%s_rel_+" % name
       
  1091 
       
  1092         super(ManyToManyField, self).contribute_to_class(cls, name)
       
  1093 
       
  1094         # The intermediate m2m model is not auto created if:
       
  1095         #  1) There is a manually specified intermediate, or
       
  1096         #  2) The class owning the m2m field is abstract.
       
  1097         if not self.rel.through and not cls._meta.abstract:
       
  1098             self.rel.through = create_many_to_many_intermediary_model(self, cls)
       
  1099 
       
  1100         # Add the descriptor for the m2m relation
       
  1101         setattr(cls, self.name, ReverseManyRelatedObjectsDescriptor(self))
       
  1102 
       
  1103         # Set up the accessor for the m2m table name for the relation
       
  1104         self.m2m_db_table = curry(self._get_m2m_db_table, cls._meta)
       
  1105 
       
  1106         # Populate some necessary rel arguments so that cross-app relations
       
  1107         # work correctly.
       
  1108         if isinstance(self.rel.through, basestring):
       
  1109             def resolve_through_model(field, model, cls):
       
  1110                 field.rel.through = model
       
  1111             add_lazy_relation(cls, self, self.rel.through, resolve_through_model)
       
  1112 
       
  1113         if isinstance(self.rel.to, basestring):
       
  1114             target = self.rel.to
       
  1115         else:
       
  1116             target = self.rel.to._meta.db_table
       
  1117         cls._meta.duplicate_targets[self.column] = (target, "m2m")
       
  1118 
       
  1119     def contribute_to_related_class(self, cls, related):
       
  1120         # Internal M2Ms (i.e., those with a related name ending with '+')
       
  1121         # don't get a related descriptor.
       
  1122         if not self.rel.is_hidden():
       
  1123             setattr(cls, related.get_accessor_name(), ManyRelatedObjectsDescriptor(related))
       
  1124 
       
  1125         # Set up the accessors for the column names on the m2m table
       
  1126         self.m2m_column_name = curry(self._get_m2m_attr, related, 'column')
       
  1127         self.m2m_reverse_name = curry(self._get_m2m_reverse_attr, related, 'column')
       
  1128 
       
  1129         self.m2m_field_name = curry(self._get_m2m_attr, related, 'name')
       
  1130         self.m2m_reverse_field_name = curry(self._get_m2m_reverse_attr, related, 'name')
       
  1131 
       
  1132     def set_attributes_from_rel(self):
       
  1133         pass
       
  1134 
       
  1135     def value_from_object(self, obj):
       
  1136         "Returns the value of this field in the given model instance."
       
  1137         return getattr(obj, self.attname).all()
       
  1138 
       
  1139     def save_form_data(self, instance, data):
       
  1140         setattr(instance, self.attname, data)
       
  1141 
       
  1142     def formfield(self, **kwargs):
       
  1143         db = kwargs.pop('using', None)
       
  1144         defaults = {
       
  1145             'form_class': forms.ModelMultipleChoiceField,
       
  1146             'queryset': self.rel.to._default_manager.using(db).complex_filter(self.rel.limit_choices_to)
       
  1147         }
       
  1148         defaults.update(kwargs)
       
  1149         # If initial is passed in, it's a list of related objects, but the
       
  1150         # MultipleChoiceField takes a list of IDs.
       
  1151         if defaults.get('initial') is not None:
       
  1152             initial = defaults['initial']
       
  1153             if callable(initial):
       
  1154                 initial = initial()
       
  1155             defaults['initial'] = [i._get_pk_val() for i in initial]
       
  1156         return super(ManyToManyField, self).formfield(**defaults)
       
  1157 
       
  1158     def db_type(self, connection):
       
  1159         # A ManyToManyField is not represented by a single column,
       
  1160         # so return None.
       
  1161         return None