Ticket #10811: related.py

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