options.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. from __future__ import unicode_literals
  2. from bisect import bisect
  3. from collections import OrderedDict
  4. from django.apps import apps
  5. from django.conf import settings
  6. from django.core.exceptions import FieldDoesNotExist
  7. from django.db.models.fields.related import ManyToManyRel
  8. from django.db.models.fields import AutoField
  9. from django.db.models.fields.proxy import OrderWrt
  10. from django.utils import six
  11. from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible
  12. from django.utils.functional import cached_property
  13. from django.utils.text import camel_case_to_spaces
  14. from django.utils.translation import activate, deactivate_all, get_language, string_concat
  15. DEFAULT_NAMES = ('verbose_name', 'verbose_name_plural', 'db_table', 'ordering',
  16. 'unique_together', 'permissions', 'get_latest_by',
  17. 'order_with_respect_to', 'app_label', 'db_tablespace',
  18. 'abstract', 'managed', 'proxy', 'swappable', 'auto_created',
  19. 'index_together', 'apps', 'default_permissions',
  20. 'select_on_save', 'default_related_name')
  21. def normalize_together(option_together):
  22. """
  23. option_together can be either a tuple of tuples, or a single
  24. tuple of two strings. Normalize it to a tuple of tuples, so that
  25. calling code can uniformly expect that.
  26. """
  27. try:
  28. if not option_together:
  29. return ()
  30. if not isinstance(option_together, (tuple, list)):
  31. raise TypeError
  32. first_element = next(iter(option_together))
  33. if not isinstance(first_element, (tuple, list)):
  34. option_together = (option_together,)
  35. # Normalize everything to tuples
  36. return tuple(tuple(ot) for ot in option_together)
  37. except TypeError:
  38. # If the value of option_together isn't valid, return it
  39. # verbatim; this will be picked up by the check framework later.
  40. return option_together
  41. @python_2_unicode_compatible
  42. class Options(object):
  43. def __init__(self, meta, app_label=None):
  44. self.local_fields = []
  45. self.local_many_to_many = []
  46. self.virtual_fields = []
  47. self.model_name = None
  48. self.verbose_name = None
  49. self.verbose_name_plural = None
  50. self.db_table = ''
  51. self.ordering = []
  52. self.unique_together = []
  53. self.index_together = []
  54. self.select_on_save = False
  55. self.default_permissions = ('add', 'change', 'delete')
  56. self.permissions = []
  57. self.object_name = None
  58. self.app_label = app_label
  59. self.get_latest_by = None
  60. self.order_with_respect_to = None
  61. self.db_tablespace = settings.DEFAULT_TABLESPACE
  62. self.meta = meta
  63. self.pk = None
  64. self.has_auto_field = False
  65. self.auto_field = None
  66. self.abstract = False
  67. self.managed = True
  68. self.proxy = False
  69. # For any class that is a proxy (including automatically created
  70. # classes for deferred object loading), proxy_for_model tells us
  71. # which class this model is proxying. Note that proxy_for_model
  72. # can create a chain of proxy models. For non-proxy models, the
  73. # variable is always None.
  74. self.proxy_for_model = None
  75. # For any non-abstract class, the concrete class is the model
  76. # in the end of the proxy_for_model chain. In particular, for
  77. # concrete models, the concrete_model is always the class itself.
  78. self.concrete_model = None
  79. self.swappable = None
  80. self.parents = OrderedDict()
  81. self.auto_created = False
  82. # To handle various inheritance situations, we need to track where
  83. # managers came from (concrete or abstract base classes). `managers`
  84. # keeps a list of 3-tuples of the form:
  85. # (creation_counter, instance, abstract(=True))
  86. self.managers = []
  87. # List of all lookups defined in ForeignKey 'limit_choices_to' options
  88. # from *other* models. Needed for some admin checks. Internal use only.
  89. self.related_fkey_lookups = []
  90. # A custom app registry to use, if you're making a separate model set.
  91. self.apps = apps
  92. self.default_related_name = None
  93. @property
  94. def app_config(self):
  95. # Don't go through get_app_config to avoid triggering imports.
  96. return self.apps.app_configs.get(self.app_label)
  97. @property
  98. def installed(self):
  99. return self.app_config is not None
  100. @property
  101. def abstract_managers(self):
  102. return [
  103. (counter, instance.name, instance) for counter, instance, abstract
  104. in self.managers if abstract
  105. ]
  106. @property
  107. def concrete_managers(self):
  108. return [
  109. (counter, instance.name, instance) for counter, instance, abstract
  110. in self.managers if not abstract
  111. ]
  112. def contribute_to_class(self, cls, name):
  113. from django.db import connection
  114. from django.db.backends.utils import truncate_name
  115. cls._meta = self
  116. self.model = cls
  117. # First, construct the default values for these options.
  118. self.object_name = cls.__name__
  119. self.model_name = self.object_name.lower()
  120. self.verbose_name = camel_case_to_spaces(self.object_name)
  121. # Store the original user-defined values for each option,
  122. # for use when serializing the model definition
  123. self.original_attrs = {}
  124. # Next, apply any overridden values from 'class Meta'.
  125. if self.meta:
  126. meta_attrs = self.meta.__dict__.copy()
  127. for name in self.meta.__dict__:
  128. # Ignore any private attributes that Django doesn't care about.
  129. # NOTE: We can't modify a dictionary's contents while looping
  130. # over it, so we loop over the *original* dictionary instead.
  131. if name.startswith('_'):
  132. del meta_attrs[name]
  133. for attr_name in DEFAULT_NAMES:
  134. if attr_name in meta_attrs:
  135. setattr(self, attr_name, meta_attrs.pop(attr_name))
  136. self.original_attrs[attr_name] = getattr(self, attr_name)
  137. elif hasattr(self.meta, attr_name):
  138. setattr(self, attr_name, getattr(self.meta, attr_name))
  139. self.original_attrs[attr_name] = getattr(self, attr_name)
  140. ut = meta_attrs.pop('unique_together', self.unique_together)
  141. self.unique_together = normalize_together(ut)
  142. it = meta_attrs.pop('index_together', self.index_together)
  143. self.index_together = normalize_together(it)
  144. # verbose_name_plural is a special case because it uses a 's'
  145. # by default.
  146. if self.verbose_name_plural is None:
  147. self.verbose_name_plural = string_concat(self.verbose_name, 's')
  148. # Any leftover attributes must be invalid.
  149. if meta_attrs != {}:
  150. raise TypeError("'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys()))
  151. else:
  152. self.verbose_name_plural = string_concat(self.verbose_name, 's')
  153. del self.meta
  154. # If the db_table wasn't provided, use the app_label + model_name.
  155. if not self.db_table:
  156. self.db_table = "%s_%s" % (self.app_label, self.model_name)
  157. self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
  158. def _prepare(self, model):
  159. if self.order_with_respect_to:
  160. self.order_with_respect_to = self.get_field(self.order_with_respect_to)
  161. self.ordering = ('_order',)
  162. if not any(isinstance(field, OrderWrt) for field in model._meta.local_fields):
  163. model.add_to_class('_order', OrderWrt())
  164. else:
  165. self.order_with_respect_to = None
  166. if self.pk is None:
  167. if self.parents:
  168. # Promote the first parent link in lieu of adding yet another
  169. # field.
  170. field = next(six.itervalues(self.parents))
  171. # Look for a local field with the same name as the
  172. # first parent link. If a local field has already been
  173. # created, use it instead of promoting the parent
  174. already_created = [fld for fld in self.local_fields if fld.name == field.name]
  175. if already_created:
  176. field = already_created[0]
  177. field.primary_key = True
  178. self.setup_pk(field)
  179. else:
  180. auto = AutoField(verbose_name='ID', primary_key=True,
  181. auto_created=True)
  182. model.add_to_class('id', auto)
  183. def add_field(self, field):
  184. # Insert the given field in the order in which it was created, using
  185. # the "creation_counter" attribute of the field.
  186. # Move many-to-many related fields from self.fields into
  187. # self.many_to_many.
  188. if field.rel and isinstance(field.rel, ManyToManyRel):
  189. self.local_many_to_many.insert(bisect(self.local_many_to_many, field), field)
  190. if hasattr(self, '_m2m_cache'):
  191. del self._m2m_cache
  192. else:
  193. self.local_fields.insert(bisect(self.local_fields, field), field)
  194. self.setup_pk(field)
  195. if hasattr(self, '_field_cache'):
  196. del self._field_cache
  197. del self._field_name_cache
  198. # The fields, concrete_fields and local_concrete_fields are
  199. # implemented as cached properties for performance reasons.
  200. # The attrs will not exists if the cached property isn't
  201. # accessed yet, hence the try-excepts.
  202. try:
  203. del self.fields
  204. except AttributeError:
  205. pass
  206. try:
  207. del self.concrete_fields
  208. except AttributeError:
  209. pass
  210. try:
  211. del self.local_concrete_fields
  212. except AttributeError:
  213. pass
  214. if hasattr(self, '_name_map'):
  215. del self._name_map
  216. def add_virtual_field(self, field):
  217. self.virtual_fields.append(field)
  218. def setup_pk(self, field):
  219. if not self.pk and field.primary_key:
  220. self.pk = field
  221. field.serialize = False
  222. def pk_index(self):
  223. """
  224. Returns the index of the primary key field in the self.concrete_fields
  225. list.
  226. """
  227. return self.concrete_fields.index(self.pk)
  228. def setup_proxy(self, target):
  229. """
  230. Does the internal setup so that the current model is a proxy for
  231. "target".
  232. """
  233. self.pk = target._meta.pk
  234. self.proxy_for_model = target
  235. self.db_table = target._meta.db_table
  236. def __repr__(self):
  237. return '<Options for %s>' % self.object_name
  238. def __str__(self):
  239. return "%s.%s" % (smart_text(self.app_label), smart_text(self.model_name))
  240. def verbose_name_raw(self):
  241. """
  242. There are a few places where the untranslated verbose name is needed
  243. (so that we get the same value regardless of currently active
  244. locale).
  245. """
  246. lang = get_language()
  247. deactivate_all()
  248. raw = force_text(self.verbose_name)
  249. activate(lang)
  250. return raw
  251. verbose_name_raw = property(verbose_name_raw)
  252. def _swapped(self):
  253. """
  254. Has this model been swapped out for another? If so, return the model
  255. name of the replacement; otherwise, return None.
  256. For historical reasons, model name lookups using get_model() are
  257. case insensitive, so we make sure we are case insensitive here.
  258. """
  259. if self.swappable:
  260. model_label = '%s.%s' % (self.app_label, self.model_name)
  261. swapped_for = getattr(settings, self.swappable, None)
  262. if swapped_for:
  263. try:
  264. swapped_label, swapped_object = swapped_for.split('.')
  265. except ValueError:
  266. # setting not in the format app_label.model_name
  267. # raising ImproperlyConfigured here causes problems with
  268. # test cleanup code - instead it is raised in get_user_model
  269. # or as part of validation.
  270. return swapped_for
  271. if '%s.%s' % (swapped_label, swapped_object.lower()) not in (None, model_label):
  272. return swapped_for
  273. return None
  274. swapped = property(_swapped)
  275. @cached_property
  276. def fields(self):
  277. """
  278. The getter for self.fields. This returns the list of field objects
  279. available to this model (including through parent models).
  280. Callers are not permitted to modify this list, since it's a reference
  281. to this instance (not a copy).
  282. """
  283. try:
  284. self._field_name_cache
  285. except AttributeError:
  286. self._fill_fields_cache()
  287. return self._field_name_cache
  288. @cached_property
  289. def concrete_fields(self):
  290. return [f for f in self.fields if f.column is not None]
  291. @cached_property
  292. def local_concrete_fields(self):
  293. return [f for f in self.local_fields if f.column is not None]
  294. def get_fields_with_model(self):
  295. """
  296. Returns a sequence of (field, model) pairs for all fields. The "model"
  297. element is None for fields on the current model. Mostly of use when
  298. constructing queries so that we know which model a field belongs to.
  299. """
  300. try:
  301. self._field_cache
  302. except AttributeError:
  303. self._fill_fields_cache()
  304. return self._field_cache
  305. def get_concrete_fields_with_model(self):
  306. return [(field, model) for field, model in self.get_fields_with_model() if
  307. field.column is not None]
  308. def _fill_fields_cache(self):
  309. cache = []
  310. for parent in self.parents:
  311. for field, model in parent._meta.get_fields_with_model():
  312. if model:
  313. cache.append((field, model))
  314. else:
  315. cache.append((field, parent))
  316. cache.extend((f, None) for f in self.local_fields)
  317. self._field_cache = tuple(cache)
  318. self._field_name_cache = [x for x, _ in cache]
  319. def _many_to_many(self):
  320. try:
  321. self._m2m_cache
  322. except AttributeError:
  323. self._fill_m2m_cache()
  324. return list(self._m2m_cache)
  325. many_to_many = property(_many_to_many)
  326. def get_m2m_with_model(self):
  327. """
  328. The many-to-many version of get_fields_with_model().
  329. """
  330. try:
  331. self._m2m_cache
  332. except AttributeError:
  333. self._fill_m2m_cache()
  334. return list(six.iteritems(self._m2m_cache))
  335. def _fill_m2m_cache(self):
  336. cache = OrderedDict()
  337. for parent in self.parents:
  338. for field, model in parent._meta.get_m2m_with_model():
  339. if model:
  340. cache[field] = model
  341. else:
  342. cache[field] = parent
  343. for field in self.local_many_to_many:
  344. cache[field] = None
  345. self._m2m_cache = cache
  346. def get_field(self, name, many_to_many=True):
  347. """
  348. Returns the requested field by name. Raises FieldDoesNotExist on error.
  349. """
  350. to_search = (self.fields + self.many_to_many) if many_to_many else self.fields
  351. for f in to_search:
  352. if f.name == name:
  353. return f
  354. raise FieldDoesNotExist('%s has no field named %r' % (self.object_name, name))
  355. def get_field_by_name(self, name):
  356. """
  357. Returns the (field_object, model, direct, m2m), where field_object is
  358. the Field instance for the given name, model is the model containing
  359. this field (None for local fields), direct is True if the field exists
  360. on this model, and m2m is True for many-to-many relations. When
  361. 'direct' is False, 'field_object' is the corresponding ForeignObjectRel
  362. for this field (since the field doesn't have an instance associated
  363. with it).
  364. Uses a cache internally, so after the first access, this is very fast.
  365. """
  366. try:
  367. try:
  368. return self._name_map[name]
  369. except AttributeError:
  370. cache = self.init_name_map()
  371. return cache[name]
  372. except KeyError:
  373. raise FieldDoesNotExist('%s has no field named %r'
  374. % (self.object_name, name))
  375. def get_all_field_names(self):
  376. """
  377. Returns a list of all field names that are possible for this model
  378. (including reverse relation names). This is used for pretty printing
  379. debugging output (a list of choices), so any internal-only field names
  380. are not included.
  381. """
  382. try:
  383. cache = self._name_map
  384. except AttributeError:
  385. cache = self.init_name_map()
  386. names = sorted(cache.keys())
  387. # Internal-only names end with "+" (symmetrical m2m related names being
  388. # the main example). Trim them.
  389. return [val for val in names if not val.endswith('+')]
  390. def init_name_map(self):
  391. """
  392. Initialises the field name -> field object mapping.
  393. """
  394. cache = {}
  395. # We intentionally handle related m2m objects first so that symmetrical
  396. # m2m accessor names can be overridden, if necessary.
  397. for f, model in self.get_all_related_m2m_objects_with_model():
  398. cache[f.field.related_query_name()] = (f, model, False, True)
  399. for f, model in self.get_all_related_objects_with_model():
  400. cache[f.field.related_query_name()] = (f, model, False, False)
  401. for f, model in self.get_m2m_with_model():
  402. cache[f.name] = cache[f.attname] = (f, model, True, True)
  403. for f, model in self.get_fields_with_model():
  404. cache[f.name] = cache[f.attname] = (f, model, True, False)
  405. for f in self.virtual_fields:
  406. if f.rel:
  407. cache[f.name] = cache[f.attname] = (
  408. f, None if f.model == self.model else f.model, True, False)
  409. if apps.ready:
  410. self._name_map = cache
  411. return cache
  412. def get_all_related_objects(self, local_only=False, include_hidden=False,
  413. include_proxy_eq=False):
  414. return [k for k, v in self.get_all_related_objects_with_model(
  415. local_only=local_only, include_hidden=include_hidden,
  416. include_proxy_eq=include_proxy_eq)]
  417. def get_all_related_objects_with_model(self, local_only=False,
  418. include_hidden=False,
  419. include_proxy_eq=False):
  420. """
  421. Returns a list of (related-object, model) pairs. Similar to
  422. get_fields_with_model().
  423. """
  424. try:
  425. self._related_objects_cache
  426. except AttributeError:
  427. self._fill_related_objects_cache()
  428. predicates = []
  429. if local_only:
  430. predicates.append(lambda k, v: not v)
  431. if not include_hidden:
  432. predicates.append(lambda k, v: not k.field.rel.is_hidden())
  433. cache = (self._related_objects_proxy_cache if include_proxy_eq
  434. else self._related_objects_cache)
  435. return [t for t in cache.items() if all(p(*t) for p in predicates)]
  436. def _fill_related_objects_cache(self):
  437. cache = OrderedDict()
  438. parent_list = self.get_parent_list()
  439. for parent in self.parents:
  440. for obj, model in parent._meta.get_all_related_objects_with_model(include_hidden=True):
  441. if (obj.field.creation_counter < 0 or obj.field.rel.parent_link) and obj.model not in parent_list:
  442. continue
  443. if not model:
  444. cache[obj] = parent
  445. else:
  446. cache[obj] = model
  447. # Collect also objects which are in relation to some proxy child/parent of self.
  448. proxy_cache = cache.copy()
  449. for klass in self.apps.get_models(include_auto_created=True):
  450. if not klass._meta.swapped:
  451. for f in klass._meta.local_fields + klass._meta.virtual_fields:
  452. if (hasattr(f, 'rel') and f.rel and not isinstance(f.rel.to, six.string_types)
  453. and f.generate_reverse_relation):
  454. if self == f.rel.to._meta:
  455. cache[f.rel] = None
  456. proxy_cache[f.rel] = None
  457. elif self.concrete_model == f.rel.to._meta.concrete_model:
  458. proxy_cache[f.rel] = None
  459. self._related_objects_cache = cache
  460. self._related_objects_proxy_cache = proxy_cache
  461. def get_all_related_many_to_many_objects(self, local_only=False):
  462. try:
  463. cache = self._related_many_to_many_cache
  464. except AttributeError:
  465. cache = self._fill_related_many_to_many_cache()
  466. if local_only:
  467. return [k for k, v in cache.items() if not v]
  468. return list(cache)
  469. def get_all_related_m2m_objects_with_model(self):
  470. """
  471. Returns a list of (related-m2m-object, model) pairs. Similar to
  472. get_fields_with_model().
  473. """
  474. try:
  475. cache = self._related_many_to_many_cache
  476. except AttributeError:
  477. cache = self._fill_related_many_to_many_cache()
  478. return list(six.iteritems(cache))
  479. def _fill_related_many_to_many_cache(self):
  480. cache = OrderedDict()
  481. parent_list = self.get_parent_list()
  482. for parent in self.parents:
  483. for obj, model in parent._meta.get_all_related_m2m_objects_with_model():
  484. if obj.field.creation_counter < 0 and obj.model not in parent_list:
  485. continue
  486. if not model:
  487. cache[obj] = parent
  488. else:
  489. cache[obj] = model
  490. for klass in self.apps.get_models():
  491. if not klass._meta.swapped:
  492. for f in klass._meta.local_many_to_many:
  493. if (f.rel
  494. and not isinstance(f.rel.to, six.string_types)
  495. and self == f.rel.to._meta):
  496. cache[f.rel] = None
  497. if apps.ready:
  498. self._related_many_to_many_cache = cache
  499. return cache
  500. def get_base_chain(self, model):
  501. """
  502. Returns a list of parent classes leading to 'model' (order from closet
  503. to most distant ancestor). This has to handle the case were 'model' is
  504. a grandparent or even more distant relation.
  505. """
  506. if not self.parents:
  507. return None
  508. if model in self.parents:
  509. return [model]
  510. for parent in self.parents:
  511. res = parent._meta.get_base_chain(model)
  512. if res:
  513. res.insert(0, parent)
  514. return res
  515. return None
  516. def get_parent_list(self):
  517. """
  518. Returns a list of all the ancestor of this model as a list. Useful for
  519. determining if something is an ancestor, regardless of lineage.
  520. """
  521. result = set()
  522. for parent in self.parents:
  523. result.add(parent)
  524. result.update(parent._meta.get_parent_list())
  525. return result
  526. def get_ancestor_link(self, ancestor):
  527. """
  528. Returns the field on the current model which points to the given
  529. "ancestor". This is possible an indirect link (a pointer to a parent
  530. model, which points, eventually, to the ancestor). Used when
  531. constructing table joins for model inheritance.
  532. Returns None if the model isn't an ancestor of this one.
  533. """
  534. if ancestor in self.parents:
  535. return self.parents[ancestor]
  536. for parent in self.parents:
  537. # Tries to get a link field from the immediate parent
  538. parent_link = parent._meta.get_ancestor_link(ancestor)
  539. if parent_link:
  540. # In case of a proxied model, the first link
  541. # of the chain to the ancestor is that parent
  542. # links
  543. return self.parents[parent] or parent_link