related.py 75 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005
  1. import functools
  2. import inspect
  3. import warnings
  4. from functools import partial
  5. from django import forms
  6. from django.apps import apps
  7. from django.conf import SettingsReference, settings
  8. from django.core import checks, exceptions
  9. from django.db import connection, router
  10. from django.db.backends import utils
  11. from django.db.models import Q
  12. from django.db.models.constants import LOOKUP_SEP
  13. from django.db.models.deletion import CASCADE, SET_DEFAULT, SET_NULL
  14. from django.db.models.query_utils import PathInfo
  15. from django.db.models.utils import make_model_tuple
  16. from django.utils.deprecation import RemovedInDjango60Warning
  17. from django.utils.functional import cached_property
  18. from django.utils.translation import gettext_lazy as _
  19. from . import Field
  20. from .mixins import FieldCacheMixin
  21. from .related_descriptors import (
  22. ForeignKeyDeferredAttribute,
  23. ForwardManyToOneDescriptor,
  24. ForwardOneToOneDescriptor,
  25. ManyToManyDescriptor,
  26. ReverseManyToOneDescriptor,
  27. ReverseOneToOneDescriptor,
  28. )
  29. from .related_lookups import (
  30. RelatedExact,
  31. RelatedGreaterThan,
  32. RelatedGreaterThanOrEqual,
  33. RelatedIn,
  34. RelatedIsNull,
  35. RelatedLessThan,
  36. RelatedLessThanOrEqual,
  37. )
  38. from .reverse_related import ForeignObjectRel, ManyToManyRel, ManyToOneRel, OneToOneRel
  39. RECURSIVE_RELATIONSHIP_CONSTANT = "self"
  40. def resolve_relation(scope_model, relation):
  41. """
  42. Transform relation into a model or fully-qualified model string of the form
  43. "app_label.ModelName", relative to scope_model.
  44. The relation argument can be:
  45. * RECURSIVE_RELATIONSHIP_CONSTANT, i.e. the string "self", in which case
  46. the model argument will be returned.
  47. * A bare model name without an app_label, in which case scope_model's
  48. app_label will be prepended.
  49. * An "app_label.ModelName" string.
  50. * A model class, which will be returned unchanged.
  51. """
  52. # Check for recursive relations
  53. if relation == RECURSIVE_RELATIONSHIP_CONSTANT:
  54. relation = scope_model
  55. # Look for an "app.Model" relation
  56. if isinstance(relation, str):
  57. if "." not in relation:
  58. relation = "%s.%s" % (scope_model._meta.app_label, relation)
  59. return relation
  60. def lazy_related_operation(function, model, *related_models, **kwargs):
  61. """
  62. Schedule `function` to be called once `model` and all `related_models`
  63. have been imported and registered with the app registry. `function` will
  64. be called with the newly-loaded model classes as its positional arguments,
  65. plus any optional keyword arguments.
  66. The `model` argument must be a model class. Each subsequent positional
  67. argument is another model, or a reference to another model - see
  68. `resolve_relation()` for the various forms these may take. Any relative
  69. references will be resolved relative to `model`.
  70. This is a convenience wrapper for `Apps.lazy_model_operation` - the app
  71. registry model used is the one found in `model._meta.apps`.
  72. """
  73. models = [model] + [resolve_relation(model, rel) for rel in related_models]
  74. model_keys = (make_model_tuple(m) for m in models)
  75. apps = model._meta.apps
  76. return apps.lazy_model_operation(partial(function, **kwargs), *model_keys)
  77. class RelatedField(FieldCacheMixin, Field):
  78. """Base class that all relational fields inherit from."""
  79. # Field flags
  80. one_to_many = False
  81. one_to_one = False
  82. many_to_many = False
  83. many_to_one = False
  84. def __init__(
  85. self,
  86. related_name=None,
  87. related_query_name=None,
  88. limit_choices_to=None,
  89. **kwargs,
  90. ):
  91. self._related_name = related_name
  92. self._related_query_name = related_query_name
  93. self._limit_choices_to = limit_choices_to
  94. super().__init__(**kwargs)
  95. @cached_property
  96. def related_model(self):
  97. # Can't cache this property until all the models are loaded.
  98. apps.check_models_ready()
  99. return self.remote_field.model
  100. def check(self, **kwargs):
  101. return [
  102. *super().check(**kwargs),
  103. *self._check_related_name_is_valid(),
  104. *self._check_related_query_name_is_valid(),
  105. *self._check_relation_model_exists(),
  106. *self._check_referencing_to_swapped_model(),
  107. *self._check_clashes(),
  108. ]
  109. def _check_related_name_is_valid(self):
  110. import keyword
  111. related_name = self.remote_field.related_name
  112. if related_name is None:
  113. return []
  114. is_valid_id = (
  115. not keyword.iskeyword(related_name) and related_name.isidentifier()
  116. )
  117. if not (is_valid_id or related_name.endswith("+")):
  118. return [
  119. checks.Error(
  120. "The name '%s' is invalid related_name for field %s.%s"
  121. % (
  122. self.remote_field.related_name,
  123. self.model._meta.object_name,
  124. self.name,
  125. ),
  126. hint=(
  127. "Related name must be a valid Python identifier or end with a "
  128. "'+'"
  129. ),
  130. obj=self,
  131. id="fields.E306",
  132. )
  133. ]
  134. return []
  135. def _check_related_query_name_is_valid(self):
  136. if self.remote_field.is_hidden():
  137. return []
  138. rel_query_name = self.related_query_name()
  139. errors = []
  140. if rel_query_name.endswith("_"):
  141. errors.append(
  142. checks.Error(
  143. "Reverse query name '%s' must not end with an underscore."
  144. % rel_query_name,
  145. hint=(
  146. "Add or change a related_name or related_query_name "
  147. "argument for this field."
  148. ),
  149. obj=self,
  150. id="fields.E308",
  151. )
  152. )
  153. if LOOKUP_SEP in rel_query_name:
  154. errors.append(
  155. checks.Error(
  156. "Reverse query name '%s' must not contain '%s'."
  157. % (rel_query_name, LOOKUP_SEP),
  158. hint=(
  159. "Add or change a related_name or related_query_name "
  160. "argument for this field."
  161. ),
  162. obj=self,
  163. id="fields.E309",
  164. )
  165. )
  166. return errors
  167. def _check_relation_model_exists(self):
  168. rel_is_missing = self.remote_field.model not in self.opts.apps.get_models()
  169. rel_is_string = isinstance(self.remote_field.model, str)
  170. model_name = (
  171. self.remote_field.model
  172. if rel_is_string
  173. else self.remote_field.model._meta.object_name
  174. )
  175. if rel_is_missing and (
  176. rel_is_string or not self.remote_field.model._meta.swapped
  177. ):
  178. return [
  179. checks.Error(
  180. "Field defines a relation with model '%s', which is either "
  181. "not installed, or is abstract." % model_name,
  182. obj=self,
  183. id="fields.E300",
  184. )
  185. ]
  186. return []
  187. def _check_referencing_to_swapped_model(self):
  188. if (
  189. self.remote_field.model not in self.opts.apps.get_models()
  190. and not isinstance(self.remote_field.model, str)
  191. and self.remote_field.model._meta.swapped
  192. ):
  193. return [
  194. checks.Error(
  195. "Field defines a relation with the model '%s', which has "
  196. "been swapped out." % self.remote_field.model._meta.label,
  197. hint="Update the relation to point at 'settings.%s'."
  198. % self.remote_field.model._meta.swappable,
  199. obj=self,
  200. id="fields.E301",
  201. )
  202. ]
  203. return []
  204. def _check_clashes(self):
  205. """Check accessor and reverse query name clashes."""
  206. from django.db.models.base import ModelBase
  207. errors = []
  208. opts = self.model._meta
  209. # f.remote_field.model may be a string instead of a model. Skip if
  210. # model name is not resolved.
  211. if not isinstance(self.remote_field.model, ModelBase):
  212. return []
  213. # Consider that we are checking field `Model.foreign` and the models
  214. # are:
  215. #
  216. # class Target(models.Model):
  217. # model = models.IntegerField()
  218. # model_set = models.IntegerField()
  219. #
  220. # class Model(models.Model):
  221. # foreign = models.ForeignKey(Target)
  222. # m2m = models.ManyToManyField(Target)
  223. # rel_opts.object_name == "Target"
  224. rel_opts = self.remote_field.model._meta
  225. # If the field doesn't install a backward relation on the target model
  226. # (so `is_hidden` returns True), then there are no clashes to check
  227. # and we can skip these fields.
  228. rel_is_hidden = self.remote_field.is_hidden()
  229. rel_name = self.remote_field.get_accessor_name() # i. e. "model_set"
  230. rel_query_name = self.related_query_name() # i. e. "model"
  231. # i.e. "app_label.Model.field".
  232. field_name = "%s.%s" % (opts.label, self.name)
  233. # Check clashes between accessor or reverse query name of `field`
  234. # and any other field name -- i.e. accessor for Model.foreign is
  235. # model_set and it clashes with Target.model_set.
  236. potential_clashes = rel_opts.fields + rel_opts.many_to_many
  237. for clash_field in potential_clashes:
  238. # i.e. "app_label.Target.model_set".
  239. clash_name = "%s.%s" % (rel_opts.label, clash_field.name)
  240. if not rel_is_hidden and clash_field.name == rel_name:
  241. errors.append(
  242. checks.Error(
  243. f"Reverse accessor '{rel_opts.object_name}.{rel_name}' "
  244. f"for '{field_name}' clashes with field name "
  245. f"'{clash_name}'.",
  246. hint=(
  247. "Rename field '%s', or add/change a related_name "
  248. "argument to the definition for field '%s'."
  249. )
  250. % (clash_name, field_name),
  251. obj=self,
  252. id="fields.E302",
  253. )
  254. )
  255. if clash_field.name == rel_query_name:
  256. errors.append(
  257. checks.Error(
  258. "Reverse query name for '%s' clashes with field name '%s'."
  259. % (field_name, clash_name),
  260. hint=(
  261. "Rename field '%s', or add/change a related_name "
  262. "argument to the definition for field '%s'."
  263. )
  264. % (clash_name, field_name),
  265. obj=self,
  266. id="fields.E303",
  267. )
  268. )
  269. # Check clashes between accessors/reverse query names of `field` and
  270. # any other field accessor -- i. e. Model.foreign accessor clashes with
  271. # Model.m2m accessor.
  272. potential_clashes = (r for r in rel_opts.related_objects if r.field is not self)
  273. for clash_field in potential_clashes:
  274. # i.e. "app_label.Model.m2m".
  275. clash_name = "%s.%s" % (
  276. clash_field.related_model._meta.label,
  277. clash_field.field.name,
  278. )
  279. if not rel_is_hidden and clash_field.get_accessor_name() == rel_name:
  280. errors.append(
  281. checks.Error(
  282. f"Reverse accessor '{rel_opts.object_name}.{rel_name}' "
  283. f"for '{field_name}' clashes with reverse accessor for "
  284. f"'{clash_name}'.",
  285. hint=(
  286. "Add or change a related_name argument "
  287. "to the definition for '%s' or '%s'."
  288. )
  289. % (field_name, clash_name),
  290. obj=self,
  291. id="fields.E304",
  292. )
  293. )
  294. if clash_field.get_accessor_name() == rel_query_name:
  295. errors.append(
  296. checks.Error(
  297. "Reverse query name for '%s' clashes with reverse query name "
  298. "for '%s'." % (field_name, clash_name),
  299. hint=(
  300. "Add or change a related_name argument "
  301. "to the definition for '%s' or '%s'."
  302. )
  303. % (field_name, clash_name),
  304. obj=self,
  305. id="fields.E305",
  306. )
  307. )
  308. return errors
  309. def db_type(self, connection):
  310. # By default related field will not have a column as it relates to
  311. # columns from another table.
  312. return None
  313. def contribute_to_class(self, cls, name, private_only=False, **kwargs):
  314. super().contribute_to_class(cls, name, private_only=private_only, **kwargs)
  315. self.opts = cls._meta
  316. if not cls._meta.abstract:
  317. if self.remote_field.related_name:
  318. related_name = self.remote_field.related_name
  319. else:
  320. related_name = self.opts.default_related_name
  321. if related_name:
  322. related_name %= {
  323. "class": cls.__name__.lower(),
  324. "model_name": cls._meta.model_name.lower(),
  325. "app_label": cls._meta.app_label.lower(),
  326. }
  327. self.remote_field.related_name = related_name
  328. if self.remote_field.related_query_name:
  329. related_query_name = self.remote_field.related_query_name % {
  330. "class": cls.__name__.lower(),
  331. "app_label": cls._meta.app_label.lower(),
  332. }
  333. self.remote_field.related_query_name = related_query_name
  334. def resolve_related_class(model, related, field):
  335. field.remote_field.model = related
  336. field.do_related_class(related, model)
  337. lazy_related_operation(
  338. resolve_related_class, cls, self.remote_field.model, field=self
  339. )
  340. def deconstruct(self):
  341. name, path, args, kwargs = super().deconstruct()
  342. if self._limit_choices_to:
  343. kwargs["limit_choices_to"] = self._limit_choices_to
  344. if self._related_name is not None:
  345. kwargs["related_name"] = self._related_name
  346. if self._related_query_name is not None:
  347. kwargs["related_query_name"] = self._related_query_name
  348. return name, path, args, kwargs
  349. def get_forward_related_filter(self, obj):
  350. """
  351. Return the keyword arguments that when supplied to
  352. self.model.object.filter(), would select all instances related through
  353. this field to the remote obj. This is used to build the querysets
  354. returned by related descriptors. obj is an instance of
  355. self.related_field.model.
  356. """
  357. return {
  358. "%s__%s" % (self.name, rh_field.name): getattr(obj, rh_field.attname)
  359. for _, rh_field in self.related_fields
  360. }
  361. def get_reverse_related_filter(self, obj):
  362. """
  363. Complement to get_forward_related_filter(). Return the keyword
  364. arguments that when passed to self.related_field.model.object.filter()
  365. select all instances of self.related_field.model related through
  366. this field to obj. obj is an instance of self.model.
  367. """
  368. base_q = Q.create(
  369. [
  370. (rh_field.attname, getattr(obj, lh_field.attname))
  371. for lh_field, rh_field in self.related_fields
  372. ]
  373. )
  374. descriptor_filter = self.get_extra_descriptor_filter(obj)
  375. if isinstance(descriptor_filter, dict):
  376. return base_q & Q(**descriptor_filter)
  377. elif descriptor_filter:
  378. return base_q & descriptor_filter
  379. return base_q
  380. @property
  381. def swappable_setting(self):
  382. """
  383. Get the setting that this is powered from for swapping, or None
  384. if it's not swapped in / marked with swappable=False.
  385. """
  386. if self.swappable:
  387. # Work out string form of "to"
  388. if isinstance(self.remote_field.model, str):
  389. to_string = self.remote_field.model
  390. else:
  391. to_string = self.remote_field.model._meta.label
  392. return apps.get_swappable_settings_name(to_string)
  393. return None
  394. def set_attributes_from_rel(self):
  395. self.name = self.name or (
  396. self.remote_field.model._meta.model_name
  397. + "_"
  398. + self.remote_field.model._meta.pk.name
  399. )
  400. if self.verbose_name is None:
  401. self.verbose_name = self.remote_field.model._meta.verbose_name
  402. self.remote_field.set_field_name()
  403. def do_related_class(self, other, cls):
  404. self.set_attributes_from_rel()
  405. self.contribute_to_related_class(other, self.remote_field)
  406. def get_limit_choices_to(self):
  407. """
  408. Return ``limit_choices_to`` for this model field.
  409. If it is a callable, it will be invoked and the result will be
  410. returned.
  411. """
  412. if callable(self.remote_field.limit_choices_to):
  413. return self.remote_field.limit_choices_to()
  414. return self.remote_field.limit_choices_to
  415. def formfield(self, **kwargs):
  416. """
  417. Pass ``limit_choices_to`` to the field being constructed.
  418. Only passes it if there is a type that supports related fields.
  419. This is a similar strategy used to pass the ``queryset`` to the field
  420. being constructed.
  421. """
  422. defaults = {}
  423. if hasattr(self.remote_field, "get_related_field"):
  424. # If this is a callable, do not invoke it here. Just pass
  425. # it in the defaults for when the form class will later be
  426. # instantiated.
  427. limit_choices_to = self.remote_field.limit_choices_to
  428. defaults.update(
  429. {
  430. "limit_choices_to": limit_choices_to,
  431. }
  432. )
  433. defaults.update(kwargs)
  434. return super().formfield(**defaults)
  435. def related_query_name(self):
  436. """
  437. Define the name that can be used to identify this related object in a
  438. table-spanning query.
  439. """
  440. return (
  441. self.remote_field.related_query_name
  442. or self.remote_field.related_name
  443. or self.opts.model_name
  444. )
  445. @property
  446. def target_field(self):
  447. """
  448. When filtering against this relation, return the field on the remote
  449. model against which the filtering should happen.
  450. """
  451. target_fields = self.path_infos[-1].target_fields
  452. if len(target_fields) > 1:
  453. raise exceptions.FieldError(
  454. "The relation has multiple target fields, but only single target field "
  455. "was asked for"
  456. )
  457. return target_fields[0]
  458. def get_cache_name(self):
  459. return self.name
  460. class ForeignObject(RelatedField):
  461. """
  462. Abstraction of the ForeignKey relation to support multi-column relations.
  463. """
  464. # Field flags
  465. many_to_many = False
  466. many_to_one = True
  467. one_to_many = False
  468. one_to_one = False
  469. requires_unique_target = True
  470. related_accessor_class = ReverseManyToOneDescriptor
  471. forward_related_accessor_class = ForwardManyToOneDescriptor
  472. rel_class = ForeignObjectRel
  473. def __init__(
  474. self,
  475. to,
  476. on_delete,
  477. from_fields,
  478. to_fields,
  479. rel=None,
  480. related_name=None,
  481. related_query_name=None,
  482. limit_choices_to=None,
  483. parent_link=False,
  484. swappable=True,
  485. **kwargs,
  486. ):
  487. if rel is None:
  488. rel = self.rel_class(
  489. self,
  490. to,
  491. related_name=related_name,
  492. related_query_name=related_query_name,
  493. limit_choices_to=limit_choices_to,
  494. parent_link=parent_link,
  495. on_delete=on_delete,
  496. )
  497. super().__init__(
  498. rel=rel,
  499. related_name=related_name,
  500. related_query_name=related_query_name,
  501. limit_choices_to=limit_choices_to,
  502. **kwargs,
  503. )
  504. self.from_fields = from_fields
  505. self.to_fields = to_fields
  506. self.swappable = swappable
  507. def __copy__(self):
  508. obj = super().__copy__()
  509. # Remove any cached PathInfo values.
  510. obj.__dict__.pop("path_infos", None)
  511. obj.__dict__.pop("reverse_path_infos", None)
  512. return obj
  513. def check(self, **kwargs):
  514. return [
  515. *super().check(**kwargs),
  516. *self._check_to_fields_exist(),
  517. *self._check_unique_target(),
  518. ]
  519. def _check_to_fields_exist(self):
  520. # Skip nonexistent models.
  521. if isinstance(self.remote_field.model, str):
  522. return []
  523. errors = []
  524. for to_field in self.to_fields:
  525. if to_field:
  526. try:
  527. self.remote_field.model._meta.get_field(to_field)
  528. except exceptions.FieldDoesNotExist:
  529. errors.append(
  530. checks.Error(
  531. "The to_field '%s' doesn't exist on the related "
  532. "model '%s'."
  533. % (to_field, self.remote_field.model._meta.label),
  534. obj=self,
  535. id="fields.E312",
  536. )
  537. )
  538. return errors
  539. def _check_unique_target(self):
  540. rel_is_string = isinstance(self.remote_field.model, str)
  541. if rel_is_string or not self.requires_unique_target:
  542. return []
  543. try:
  544. self.foreign_related_fields
  545. except exceptions.FieldDoesNotExist:
  546. return []
  547. if not self.foreign_related_fields:
  548. return []
  549. unique_foreign_fields = {
  550. frozenset([f.name])
  551. for f in self.remote_field.model._meta.get_fields()
  552. if getattr(f, "unique", False)
  553. }
  554. unique_foreign_fields.update(
  555. {frozenset(ut) for ut in self.remote_field.model._meta.unique_together}
  556. )
  557. unique_foreign_fields.update(
  558. {
  559. frozenset(uc.fields)
  560. for uc in self.remote_field.model._meta.total_unique_constraints
  561. }
  562. )
  563. foreign_fields = {f.name for f in self.foreign_related_fields}
  564. has_unique_constraint = any(u <= foreign_fields for u in unique_foreign_fields)
  565. if not has_unique_constraint and len(self.foreign_related_fields) > 1:
  566. field_combination = ", ".join(
  567. "'%s'" % rel_field.name for rel_field in self.foreign_related_fields
  568. )
  569. model_name = self.remote_field.model.__name__
  570. return [
  571. checks.Error(
  572. "No subset of the fields %s on model '%s' is unique."
  573. % (field_combination, model_name),
  574. hint=(
  575. "Mark a single field as unique=True or add a set of "
  576. "fields to a unique constraint (via unique_together "
  577. "or a UniqueConstraint (without condition) in the "
  578. "model Meta.constraints)."
  579. ),
  580. obj=self,
  581. id="fields.E310",
  582. )
  583. ]
  584. elif not has_unique_constraint:
  585. field_name = self.foreign_related_fields[0].name
  586. model_name = self.remote_field.model.__name__
  587. return [
  588. checks.Error(
  589. "'%s.%s' must be unique because it is referenced by "
  590. "a foreign key." % (model_name, field_name),
  591. hint=(
  592. "Add unique=True to this field or add a "
  593. "UniqueConstraint (without condition) in the model "
  594. "Meta.constraints."
  595. ),
  596. obj=self,
  597. id="fields.E311",
  598. )
  599. ]
  600. else:
  601. return []
  602. def deconstruct(self):
  603. name, path, args, kwargs = super().deconstruct()
  604. kwargs["on_delete"] = self.remote_field.on_delete
  605. kwargs["from_fields"] = self.from_fields
  606. kwargs["to_fields"] = self.to_fields
  607. if self.remote_field.parent_link:
  608. kwargs["parent_link"] = self.remote_field.parent_link
  609. if isinstance(self.remote_field.model, str):
  610. if "." in self.remote_field.model:
  611. app_label, model_name = self.remote_field.model.split(".")
  612. kwargs["to"] = "%s.%s" % (app_label, model_name.lower())
  613. else:
  614. kwargs["to"] = self.remote_field.model.lower()
  615. else:
  616. kwargs["to"] = self.remote_field.model._meta.label_lower
  617. # If swappable is True, then see if we're actually pointing to the target
  618. # of a swap.
  619. swappable_setting = self.swappable_setting
  620. if swappable_setting is not None:
  621. # If it's already a settings reference, error
  622. if hasattr(kwargs["to"], "setting_name"):
  623. if kwargs["to"].setting_name != swappable_setting:
  624. raise ValueError(
  625. "Cannot deconstruct a ForeignKey pointing to a model "
  626. "that is swapped in place of more than one model (%s and %s)"
  627. % (kwargs["to"].setting_name, swappable_setting)
  628. )
  629. # Set it
  630. kwargs["to"] = SettingsReference(
  631. kwargs["to"],
  632. swappable_setting,
  633. )
  634. return name, path, args, kwargs
  635. def resolve_related_fields(self):
  636. if not self.from_fields or len(self.from_fields) != len(self.to_fields):
  637. raise ValueError(
  638. "Foreign Object from and to fields must be the same non-zero length"
  639. )
  640. if isinstance(self.remote_field.model, str):
  641. raise ValueError(
  642. "Related model %r cannot be resolved" % self.remote_field.model
  643. )
  644. related_fields = []
  645. for index in range(len(self.from_fields)):
  646. from_field_name = self.from_fields[index]
  647. to_field_name = self.to_fields[index]
  648. from_field = (
  649. self
  650. if from_field_name == RECURSIVE_RELATIONSHIP_CONSTANT
  651. else self.opts.get_field(from_field_name)
  652. )
  653. to_field = (
  654. self.remote_field.model._meta.pk
  655. if to_field_name is None
  656. else self.remote_field.model._meta.get_field(to_field_name)
  657. )
  658. related_fields.append((from_field, to_field))
  659. return related_fields
  660. @cached_property
  661. def related_fields(self):
  662. return self.resolve_related_fields()
  663. @cached_property
  664. def reverse_related_fields(self):
  665. return [(rhs_field, lhs_field) for lhs_field, rhs_field in self.related_fields]
  666. @cached_property
  667. def local_related_fields(self):
  668. return tuple(lhs_field for lhs_field, rhs_field in self.related_fields)
  669. @cached_property
  670. def foreign_related_fields(self):
  671. return tuple(
  672. rhs_field for lhs_field, rhs_field in self.related_fields if rhs_field
  673. )
  674. def get_local_related_value(self, instance):
  675. return self.get_instance_value_for_fields(instance, self.local_related_fields)
  676. def get_foreign_related_value(self, instance):
  677. return self.get_instance_value_for_fields(instance, self.foreign_related_fields)
  678. @staticmethod
  679. def get_instance_value_for_fields(instance, fields):
  680. ret = []
  681. opts = instance._meta
  682. for field in fields:
  683. # Gotcha: in some cases (like fixture loading) a model can have
  684. # different values in parent_ptr_id and parent's id. So, use
  685. # instance.pk (that is, parent_ptr_id) when asked for instance.id.
  686. if field.primary_key:
  687. possible_parent_link = opts.get_ancestor_link(field.model)
  688. if (
  689. not possible_parent_link
  690. or possible_parent_link.primary_key
  691. or possible_parent_link.model._meta.abstract
  692. ):
  693. ret.append(instance.pk)
  694. continue
  695. ret.append(getattr(instance, field.attname))
  696. return tuple(ret)
  697. def get_attname_column(self):
  698. attname, column = super().get_attname_column()
  699. return attname, None
  700. def get_joining_columns(self, reverse_join=False):
  701. warnings.warn(
  702. "ForeignObject.get_joining_columns() is deprecated. Use "
  703. "get_joining_fields() instead.",
  704. RemovedInDjango60Warning,
  705. )
  706. source = self.reverse_related_fields if reverse_join else self.related_fields
  707. return tuple(
  708. (lhs_field.column, rhs_field.column) for lhs_field, rhs_field in source
  709. )
  710. def get_reverse_joining_columns(self):
  711. warnings.warn(
  712. "ForeignObject.get_reverse_joining_columns() is deprecated. Use "
  713. "get_reverse_joining_fields() instead.",
  714. RemovedInDjango60Warning,
  715. )
  716. return self.get_joining_columns(reverse_join=True)
  717. def get_joining_fields(self, reverse_join=False):
  718. return tuple(
  719. self.reverse_related_fields if reverse_join else self.related_fields
  720. )
  721. def get_reverse_joining_fields(self):
  722. return self.get_joining_fields(reverse_join=True)
  723. def get_extra_descriptor_filter(self, instance):
  724. """
  725. Return an extra filter condition for related object fetching when
  726. user does 'instance.fieldname', that is the extra filter is used in
  727. the descriptor of the field.
  728. The filter should be either a dict usable in .filter(**kwargs) call or
  729. a Q-object. The condition will be ANDed together with the relation's
  730. joining columns.
  731. A parallel method is get_extra_restriction() which is used in
  732. JOIN and subquery conditions.
  733. """
  734. return {}
  735. def get_extra_restriction(self, alias, related_alias):
  736. """
  737. Return a pair condition used for joining and subquery pushdown. The
  738. condition is something that responds to as_sql(compiler, connection)
  739. method.
  740. Note that currently referring both the 'alias' and 'related_alias'
  741. will not work in some conditions, like subquery pushdown.
  742. A parallel method is get_extra_descriptor_filter() which is used in
  743. instance.fieldname related object fetching.
  744. """
  745. return None
  746. def get_path_info(self, filtered_relation=None):
  747. """Get path from this field to the related model."""
  748. opts = self.remote_field.model._meta
  749. from_opts = self.model._meta
  750. return [
  751. PathInfo(
  752. from_opts=from_opts,
  753. to_opts=opts,
  754. target_fields=self.foreign_related_fields,
  755. join_field=self,
  756. m2m=False,
  757. direct=True,
  758. filtered_relation=filtered_relation,
  759. )
  760. ]
  761. @cached_property
  762. def path_infos(self):
  763. return self.get_path_info()
  764. def get_reverse_path_info(self, filtered_relation=None):
  765. """Get path from the related model to this field's model."""
  766. opts = self.model._meta
  767. from_opts = self.remote_field.model._meta
  768. return [
  769. PathInfo(
  770. from_opts=from_opts,
  771. to_opts=opts,
  772. target_fields=(opts.pk,),
  773. join_field=self.remote_field,
  774. m2m=not self.unique,
  775. direct=False,
  776. filtered_relation=filtered_relation,
  777. )
  778. ]
  779. @cached_property
  780. def reverse_path_infos(self):
  781. return self.get_reverse_path_info()
  782. @classmethod
  783. @functools.cache
  784. def get_class_lookups(cls):
  785. bases = inspect.getmro(cls)
  786. bases = bases[: bases.index(ForeignObject) + 1]
  787. class_lookups = [parent.__dict__.get("class_lookups", {}) for parent in bases]
  788. return cls.merge_dicts(class_lookups)
  789. def contribute_to_class(self, cls, name, private_only=False, **kwargs):
  790. super().contribute_to_class(cls, name, private_only=private_only, **kwargs)
  791. setattr(cls, self.name, self.forward_related_accessor_class(self))
  792. def contribute_to_related_class(self, cls, related):
  793. # Internal FK's - i.e., those with a related name ending with '+' -
  794. # and swapped models don't get a related descriptor.
  795. if (
  796. not self.remote_field.is_hidden()
  797. and not related.related_model._meta.swapped
  798. ):
  799. setattr(
  800. cls._meta.concrete_model,
  801. related.get_accessor_name(),
  802. self.related_accessor_class(related),
  803. )
  804. # While 'limit_choices_to' might be a callable, simply pass
  805. # it along for later - this is too early because it's still
  806. # model load time.
  807. if self.remote_field.limit_choices_to:
  808. cls._meta.related_fkey_lookups.append(
  809. self.remote_field.limit_choices_to
  810. )
  811. ForeignObject.register_lookup(RelatedIn)
  812. ForeignObject.register_lookup(RelatedExact)
  813. ForeignObject.register_lookup(RelatedLessThan)
  814. ForeignObject.register_lookup(RelatedGreaterThan)
  815. ForeignObject.register_lookup(RelatedGreaterThanOrEqual)
  816. ForeignObject.register_lookup(RelatedLessThanOrEqual)
  817. ForeignObject.register_lookup(RelatedIsNull)
  818. class ForeignKey(ForeignObject):
  819. """
  820. Provide a many-to-one relation by adding a column to the local model
  821. to hold the remote value.
  822. By default ForeignKey will target the pk of the remote model but this
  823. behavior can be changed by using the ``to_field`` argument.
  824. """
  825. descriptor_class = ForeignKeyDeferredAttribute
  826. # Field flags
  827. many_to_many = False
  828. many_to_one = True
  829. one_to_many = False
  830. one_to_one = False
  831. rel_class = ManyToOneRel
  832. empty_strings_allowed = False
  833. default_error_messages = {
  834. "invalid": _("%(model)s instance with %(field)s %(value)r does not exist.")
  835. }
  836. description = _("Foreign Key (type determined by related field)")
  837. def __init__(
  838. self,
  839. to,
  840. on_delete,
  841. related_name=None,
  842. related_query_name=None,
  843. limit_choices_to=None,
  844. parent_link=False,
  845. to_field=None,
  846. db_constraint=True,
  847. **kwargs,
  848. ):
  849. try:
  850. to._meta.model_name
  851. except AttributeError:
  852. if not isinstance(to, str):
  853. raise TypeError(
  854. "%s(%r) is invalid. First parameter to ForeignKey must be "
  855. "either a model, a model name, or the string %r"
  856. % (
  857. self.__class__.__name__,
  858. to,
  859. RECURSIVE_RELATIONSHIP_CONSTANT,
  860. )
  861. )
  862. else:
  863. # For backwards compatibility purposes, we need to *try* and set
  864. # the to_field during FK construction. It won't be guaranteed to
  865. # be correct until contribute_to_class is called. Refs #12190.
  866. to_field = to_field or (to._meta.pk and to._meta.pk.name)
  867. if not callable(on_delete):
  868. raise TypeError("on_delete must be callable.")
  869. kwargs["rel"] = self.rel_class(
  870. self,
  871. to,
  872. to_field,
  873. related_name=related_name,
  874. related_query_name=related_query_name,
  875. limit_choices_to=limit_choices_to,
  876. parent_link=parent_link,
  877. on_delete=on_delete,
  878. )
  879. kwargs.setdefault("db_index", True)
  880. super().__init__(
  881. to,
  882. on_delete,
  883. related_name=related_name,
  884. related_query_name=related_query_name,
  885. limit_choices_to=limit_choices_to,
  886. from_fields=[RECURSIVE_RELATIONSHIP_CONSTANT],
  887. to_fields=[to_field],
  888. **kwargs,
  889. )
  890. self.db_constraint = db_constraint
  891. def __class_getitem__(cls, *args, **kwargs):
  892. return cls
  893. def check(self, **kwargs):
  894. return [
  895. *super().check(**kwargs),
  896. *self._check_on_delete(),
  897. *self._check_unique(),
  898. ]
  899. def _check_on_delete(self):
  900. on_delete = getattr(self.remote_field, "on_delete", None)
  901. if on_delete == SET_NULL and not self.null:
  902. return [
  903. checks.Error(
  904. "Field specifies on_delete=SET_NULL, but cannot be null.",
  905. hint=(
  906. "Set null=True argument on the field, or change the on_delete "
  907. "rule."
  908. ),
  909. obj=self,
  910. id="fields.E320",
  911. )
  912. ]
  913. elif on_delete == SET_DEFAULT and not self.has_default():
  914. return [
  915. checks.Error(
  916. "Field specifies on_delete=SET_DEFAULT, but has no default value.",
  917. hint="Set a default value, or change the on_delete rule.",
  918. obj=self,
  919. id="fields.E321",
  920. )
  921. ]
  922. else:
  923. return []
  924. def _check_unique(self, **kwargs):
  925. return (
  926. [
  927. checks.Warning(
  928. "Setting unique=True on a ForeignKey has the same effect as using "
  929. "a OneToOneField.",
  930. hint=(
  931. "ForeignKey(unique=True) is usually better served by a "
  932. "OneToOneField."
  933. ),
  934. obj=self,
  935. id="fields.W342",
  936. )
  937. ]
  938. if self.unique
  939. else []
  940. )
  941. def deconstruct(self):
  942. name, path, args, kwargs = super().deconstruct()
  943. del kwargs["to_fields"]
  944. del kwargs["from_fields"]
  945. # Handle the simpler arguments
  946. if self.db_index:
  947. del kwargs["db_index"]
  948. else:
  949. kwargs["db_index"] = False
  950. if self.db_constraint is not True:
  951. kwargs["db_constraint"] = self.db_constraint
  952. # Rel needs more work.
  953. to_meta = getattr(self.remote_field.model, "_meta", None)
  954. if self.remote_field.field_name and (
  955. not to_meta
  956. or (to_meta.pk and self.remote_field.field_name != to_meta.pk.name)
  957. ):
  958. kwargs["to_field"] = self.remote_field.field_name
  959. return name, path, args, kwargs
  960. def to_python(self, value):
  961. return self.target_field.to_python(value)
  962. @property
  963. def target_field(self):
  964. return self.foreign_related_fields[0]
  965. def validate(self, value, model_instance):
  966. if self.remote_field.parent_link:
  967. return
  968. super().validate(value, model_instance)
  969. if value is None:
  970. return
  971. using = router.db_for_read(self.remote_field.model, instance=model_instance)
  972. qs = self.remote_field.model._base_manager.using(using).filter(
  973. **{self.remote_field.field_name: value}
  974. )
  975. qs = qs.complex_filter(self.get_limit_choices_to())
  976. if not qs.exists():
  977. raise exceptions.ValidationError(
  978. self.error_messages["invalid"],
  979. code="invalid",
  980. params={
  981. "model": self.remote_field.model._meta.verbose_name,
  982. "pk": value,
  983. "field": self.remote_field.field_name,
  984. "value": value,
  985. }, # 'pk' is included for backwards compatibility
  986. )
  987. def resolve_related_fields(self):
  988. related_fields = super().resolve_related_fields()
  989. for from_field, to_field in related_fields:
  990. if (
  991. to_field
  992. and to_field.model != self.remote_field.model._meta.concrete_model
  993. ):
  994. raise exceptions.FieldError(
  995. "'%s.%s' refers to field '%s' which is not local to model "
  996. "'%s'."
  997. % (
  998. self.model._meta.label,
  999. self.name,
  1000. to_field.name,
  1001. self.remote_field.model._meta.concrete_model._meta.label,
  1002. )
  1003. )
  1004. return related_fields
  1005. def get_attname(self):
  1006. return "%s_id" % self.name
  1007. def get_attname_column(self):
  1008. attname = self.get_attname()
  1009. column = self.db_column or attname
  1010. return attname, column
  1011. def get_default(self):
  1012. """Return the to_field if the default value is an object."""
  1013. field_default = super().get_default()
  1014. if isinstance(field_default, self.remote_field.model):
  1015. return getattr(field_default, self.target_field.attname)
  1016. return field_default
  1017. def get_db_prep_save(self, value, connection):
  1018. if value is None or (
  1019. value == ""
  1020. and (
  1021. not self.target_field.empty_strings_allowed
  1022. or connection.features.interprets_empty_strings_as_nulls
  1023. )
  1024. ):
  1025. return None
  1026. else:
  1027. return self.target_field.get_db_prep_save(value, connection=connection)
  1028. def get_db_prep_value(self, value, connection, prepared=False):
  1029. return self.target_field.get_db_prep_value(value, connection, prepared)
  1030. def get_prep_value(self, value):
  1031. return self.target_field.get_prep_value(value)
  1032. def contribute_to_related_class(self, cls, related):
  1033. super().contribute_to_related_class(cls, related)
  1034. if self.remote_field.field_name is None:
  1035. self.remote_field.field_name = cls._meta.pk.name
  1036. def formfield(self, *, using=None, **kwargs):
  1037. if isinstance(self.remote_field.model, str):
  1038. raise ValueError(
  1039. "Cannot create form field for %r yet, because "
  1040. "its related model %r has not been loaded yet"
  1041. % (self.name, self.remote_field.model)
  1042. )
  1043. return super().formfield(
  1044. **{
  1045. "form_class": forms.ModelChoiceField,
  1046. "queryset": self.remote_field.model._default_manager.using(using),
  1047. "to_field_name": self.remote_field.field_name,
  1048. **kwargs,
  1049. "blank": self.blank,
  1050. }
  1051. )
  1052. def db_check(self, connection):
  1053. return None
  1054. def db_type(self, connection):
  1055. return self.target_field.rel_db_type(connection=connection)
  1056. def cast_db_type(self, connection):
  1057. return self.target_field.cast_db_type(connection=connection)
  1058. def db_parameters(self, connection):
  1059. target_db_parameters = self.target_field.db_parameters(connection)
  1060. return {
  1061. "type": self.db_type(connection),
  1062. "check": self.db_check(connection),
  1063. "collation": target_db_parameters.get("collation"),
  1064. }
  1065. def convert_empty_strings(self, value, expression, connection):
  1066. if (not value) and isinstance(value, str):
  1067. return None
  1068. return value
  1069. def get_db_converters(self, connection):
  1070. converters = super().get_db_converters(connection)
  1071. if connection.features.interprets_empty_strings_as_nulls:
  1072. converters += [self.convert_empty_strings]
  1073. return converters
  1074. def get_col(self, alias, output_field=None):
  1075. if output_field is None:
  1076. output_field = self.target_field
  1077. while isinstance(output_field, ForeignKey):
  1078. output_field = output_field.target_field
  1079. if output_field is self:
  1080. raise ValueError("Cannot resolve output_field.")
  1081. return super().get_col(alias, output_field)
  1082. class OneToOneField(ForeignKey):
  1083. """
  1084. A OneToOneField is essentially the same as a ForeignKey, with the exception
  1085. that it always carries a "unique" constraint with it and the reverse
  1086. relation always returns the object pointed to (since there will only ever
  1087. be one), rather than returning a list.
  1088. """
  1089. # Field flags
  1090. many_to_many = False
  1091. many_to_one = False
  1092. one_to_many = False
  1093. one_to_one = True
  1094. related_accessor_class = ReverseOneToOneDescriptor
  1095. forward_related_accessor_class = ForwardOneToOneDescriptor
  1096. rel_class = OneToOneRel
  1097. description = _("One-to-one relationship")
  1098. def __init__(self, to, on_delete, to_field=None, **kwargs):
  1099. kwargs["unique"] = True
  1100. super().__init__(to, on_delete, to_field=to_field, **kwargs)
  1101. def deconstruct(self):
  1102. name, path, args, kwargs = super().deconstruct()
  1103. if "unique" in kwargs:
  1104. del kwargs["unique"]
  1105. return name, path, args, kwargs
  1106. def formfield(self, **kwargs):
  1107. if self.remote_field.parent_link:
  1108. return None
  1109. return super().formfield(**kwargs)
  1110. def save_form_data(self, instance, data):
  1111. if isinstance(data, self.remote_field.model):
  1112. setattr(instance, self.name, data)
  1113. else:
  1114. setattr(instance, self.attname, data)
  1115. # Remote field object must be cleared otherwise Model.save()
  1116. # will reassign attname using the related object pk.
  1117. if data is None:
  1118. setattr(instance, self.name, data)
  1119. def _check_unique(self, **kwargs):
  1120. # Override ForeignKey since check isn't applicable here.
  1121. return []
  1122. def create_many_to_many_intermediary_model(field, klass):
  1123. from django.db import models
  1124. def set_managed(model, related, through):
  1125. through._meta.managed = model._meta.managed or related._meta.managed
  1126. to_model = resolve_relation(klass, field.remote_field.model)
  1127. name = "%s_%s" % (klass._meta.object_name, field.name)
  1128. lazy_related_operation(set_managed, klass, to_model, name)
  1129. to = make_model_tuple(to_model)[1]
  1130. from_ = klass._meta.model_name
  1131. if to == from_:
  1132. to = "to_%s" % to
  1133. from_ = "from_%s" % from_
  1134. meta = type(
  1135. "Meta",
  1136. (),
  1137. {
  1138. "db_table": field._get_m2m_db_table(klass._meta),
  1139. "auto_created": klass,
  1140. "app_label": klass._meta.app_label,
  1141. "db_tablespace": klass._meta.db_tablespace,
  1142. "unique_together": (from_, to),
  1143. "verbose_name": _("%(from)s-%(to)s relationship")
  1144. % {"from": from_, "to": to},
  1145. "verbose_name_plural": _("%(from)s-%(to)s relationships")
  1146. % {"from": from_, "to": to},
  1147. "apps": field.model._meta.apps,
  1148. },
  1149. )
  1150. # Construct and return the new class.
  1151. return type(
  1152. name,
  1153. (models.Model,),
  1154. {
  1155. "Meta": meta,
  1156. "__module__": klass.__module__,
  1157. from_: models.ForeignKey(
  1158. klass,
  1159. related_name="%s+" % name,
  1160. db_tablespace=field.db_tablespace,
  1161. db_constraint=field.remote_field.db_constraint,
  1162. on_delete=CASCADE,
  1163. ),
  1164. to: models.ForeignKey(
  1165. to_model,
  1166. related_name="%s+" % name,
  1167. db_tablespace=field.db_tablespace,
  1168. db_constraint=field.remote_field.db_constraint,
  1169. on_delete=CASCADE,
  1170. ),
  1171. },
  1172. )
  1173. class ManyToManyField(RelatedField):
  1174. """
  1175. Provide a many-to-many relation by using an intermediary model that
  1176. holds two ForeignKey fields pointed at the two sides of the relation.
  1177. Unless a ``through`` model was provided, ManyToManyField will use the
  1178. create_many_to_many_intermediary_model factory to automatically generate
  1179. the intermediary model.
  1180. """
  1181. # Field flags
  1182. many_to_many = True
  1183. many_to_one = False
  1184. one_to_many = False
  1185. one_to_one = False
  1186. rel_class = ManyToManyRel
  1187. description = _("Many-to-many relationship")
  1188. def __init__(
  1189. self,
  1190. to,
  1191. related_name=None,
  1192. related_query_name=None,
  1193. limit_choices_to=None,
  1194. symmetrical=None,
  1195. through=None,
  1196. through_fields=None,
  1197. db_constraint=True,
  1198. db_table=None,
  1199. swappable=True,
  1200. **kwargs,
  1201. ):
  1202. try:
  1203. to._meta
  1204. except AttributeError:
  1205. if not isinstance(to, str):
  1206. raise TypeError(
  1207. "%s(%r) is invalid. First parameter to ManyToManyField "
  1208. "must be either a model, a model name, or the string %r"
  1209. % (
  1210. self.__class__.__name__,
  1211. to,
  1212. RECURSIVE_RELATIONSHIP_CONSTANT,
  1213. )
  1214. )
  1215. if symmetrical is None:
  1216. symmetrical = to == RECURSIVE_RELATIONSHIP_CONSTANT
  1217. if through is not None and db_table is not None:
  1218. raise ValueError(
  1219. "Cannot specify a db_table if an intermediary model is used."
  1220. )
  1221. kwargs["rel"] = self.rel_class(
  1222. self,
  1223. to,
  1224. related_name=related_name,
  1225. related_query_name=related_query_name,
  1226. limit_choices_to=limit_choices_to,
  1227. symmetrical=symmetrical,
  1228. through=through,
  1229. through_fields=through_fields,
  1230. db_constraint=db_constraint,
  1231. )
  1232. self.has_null_arg = "null" in kwargs
  1233. super().__init__(
  1234. related_name=related_name,
  1235. related_query_name=related_query_name,
  1236. limit_choices_to=limit_choices_to,
  1237. **kwargs,
  1238. )
  1239. self.db_table = db_table
  1240. self.swappable = swappable
  1241. def check(self, **kwargs):
  1242. return [
  1243. *super().check(**kwargs),
  1244. *self._check_unique(**kwargs),
  1245. *self._check_relationship_model(**kwargs),
  1246. *self._check_ignored_options(**kwargs),
  1247. *self._check_table_uniqueness(**kwargs),
  1248. ]
  1249. def _check_unique(self, **kwargs):
  1250. if self.unique:
  1251. return [
  1252. checks.Error(
  1253. "ManyToManyFields cannot be unique.",
  1254. obj=self,
  1255. id="fields.E330",
  1256. )
  1257. ]
  1258. return []
  1259. def _check_ignored_options(self, **kwargs):
  1260. warnings = []
  1261. if self.has_null_arg:
  1262. warnings.append(
  1263. checks.Warning(
  1264. "null has no effect on ManyToManyField.",
  1265. obj=self,
  1266. id="fields.W340",
  1267. )
  1268. )
  1269. if self._validators:
  1270. warnings.append(
  1271. checks.Warning(
  1272. "ManyToManyField does not support validators.",
  1273. obj=self,
  1274. id="fields.W341",
  1275. )
  1276. )
  1277. if self.remote_field.symmetrical and self._related_name:
  1278. warnings.append(
  1279. checks.Warning(
  1280. "related_name has no effect on ManyToManyField "
  1281. 'with a symmetrical relationship, e.g. to "self".',
  1282. obj=self,
  1283. id="fields.W345",
  1284. )
  1285. )
  1286. if self.db_comment:
  1287. warnings.append(
  1288. checks.Warning(
  1289. "db_comment has no effect on ManyToManyField.",
  1290. obj=self,
  1291. id="fields.W346",
  1292. )
  1293. )
  1294. return warnings
  1295. def _check_relationship_model(self, from_model=None, **kwargs):
  1296. if hasattr(self.remote_field.through, "_meta"):
  1297. qualified_model_name = "%s.%s" % (
  1298. self.remote_field.through._meta.app_label,
  1299. self.remote_field.through.__name__,
  1300. )
  1301. else:
  1302. qualified_model_name = self.remote_field.through
  1303. errors = []
  1304. if self.remote_field.through not in self.opts.apps.get_models(
  1305. include_auto_created=True
  1306. ):
  1307. # The relationship model is not installed.
  1308. errors.append(
  1309. checks.Error(
  1310. "Field specifies a many-to-many relation through model "
  1311. "'%s', which has not been installed." % qualified_model_name,
  1312. obj=self,
  1313. id="fields.E331",
  1314. )
  1315. )
  1316. else:
  1317. assert from_model is not None, (
  1318. "ManyToManyField with intermediate "
  1319. "tables cannot be checked if you don't pass the model "
  1320. "where the field is attached to."
  1321. )
  1322. # Set some useful local variables
  1323. to_model = resolve_relation(from_model, self.remote_field.model)
  1324. from_model_name = from_model._meta.object_name
  1325. if isinstance(to_model, str):
  1326. to_model_name = to_model
  1327. else:
  1328. to_model_name = to_model._meta.object_name
  1329. relationship_model_name = self.remote_field.through._meta.object_name
  1330. self_referential = from_model == to_model
  1331. # Count foreign keys in intermediate model
  1332. if self_referential:
  1333. seen_self = sum(
  1334. from_model == getattr(field.remote_field, "model", None)
  1335. for field in self.remote_field.through._meta.fields
  1336. )
  1337. if seen_self > 2 and not self.remote_field.through_fields:
  1338. errors.append(
  1339. checks.Error(
  1340. "The model is used as an intermediate model by "
  1341. "'%s', but it has more than two foreign keys "
  1342. "to '%s', which is ambiguous. You must specify "
  1343. "which two foreign keys Django should use via the "
  1344. "through_fields keyword argument."
  1345. % (self, from_model_name),
  1346. hint=(
  1347. "Use through_fields to specify which two foreign keys "
  1348. "Django should use."
  1349. ),
  1350. obj=self.remote_field.through,
  1351. id="fields.E333",
  1352. )
  1353. )
  1354. else:
  1355. # Count foreign keys in relationship model
  1356. seen_from = sum(
  1357. from_model == getattr(field.remote_field, "model", None)
  1358. for field in self.remote_field.through._meta.fields
  1359. )
  1360. seen_to = sum(
  1361. to_model == getattr(field.remote_field, "model", None)
  1362. for field in self.remote_field.through._meta.fields
  1363. )
  1364. if seen_from > 1 and not self.remote_field.through_fields:
  1365. errors.append(
  1366. checks.Error(
  1367. (
  1368. "The model is used as an intermediate model by "
  1369. "'%s', but it has more than one foreign key "
  1370. "from '%s', which is ambiguous. You must specify "
  1371. "which foreign key Django should use via the "
  1372. "through_fields keyword argument."
  1373. )
  1374. % (self, from_model_name),
  1375. hint=(
  1376. "If you want to create a recursive relationship, "
  1377. 'use ManyToManyField("%s", through="%s").'
  1378. )
  1379. % (
  1380. RECURSIVE_RELATIONSHIP_CONSTANT,
  1381. relationship_model_name,
  1382. ),
  1383. obj=self,
  1384. id="fields.E334",
  1385. )
  1386. )
  1387. if seen_to > 1 and not self.remote_field.through_fields:
  1388. errors.append(
  1389. checks.Error(
  1390. "The model is used as an intermediate model by "
  1391. "'%s', but it has more than one foreign key "
  1392. "to '%s', which is ambiguous. You must specify "
  1393. "which foreign key Django should use via the "
  1394. "through_fields keyword argument." % (self, to_model_name),
  1395. hint=(
  1396. "If you want to create a recursive relationship, "
  1397. 'use ManyToManyField("%s", through="%s").'
  1398. )
  1399. % (
  1400. RECURSIVE_RELATIONSHIP_CONSTANT,
  1401. relationship_model_name,
  1402. ),
  1403. obj=self,
  1404. id="fields.E335",
  1405. )
  1406. )
  1407. if seen_from == 0 or seen_to == 0:
  1408. errors.append(
  1409. checks.Error(
  1410. "The model is used as an intermediate model by "
  1411. "'%s', but it does not have a foreign key to '%s' or '%s'."
  1412. % (self, from_model_name, to_model_name),
  1413. obj=self.remote_field.through,
  1414. id="fields.E336",
  1415. )
  1416. )
  1417. # Validate `through_fields`.
  1418. if self.remote_field.through_fields is not None:
  1419. # Validate that we're given an iterable of at least two items
  1420. # and that none of them is "falsy".
  1421. if not (
  1422. len(self.remote_field.through_fields) >= 2
  1423. and self.remote_field.through_fields[0]
  1424. and self.remote_field.through_fields[1]
  1425. ):
  1426. errors.append(
  1427. checks.Error(
  1428. "Field specifies 'through_fields' but does not provide "
  1429. "the names of the two link fields that should be used "
  1430. "for the relation through model '%s'." % qualified_model_name,
  1431. hint=(
  1432. "Make sure you specify 'through_fields' as "
  1433. "through_fields=('field1', 'field2')"
  1434. ),
  1435. obj=self,
  1436. id="fields.E337",
  1437. )
  1438. )
  1439. # Validate the given through fields -- they should be actual
  1440. # fields on the through model, and also be foreign keys to the
  1441. # expected models.
  1442. else:
  1443. assert from_model is not None, (
  1444. "ManyToManyField with intermediate "
  1445. "tables cannot be checked if you don't pass the model "
  1446. "where the field is attached to."
  1447. )
  1448. source, through, target = (
  1449. from_model,
  1450. self.remote_field.through,
  1451. self.remote_field.model,
  1452. )
  1453. source_field_name, target_field_name = self.remote_field.through_fields[
  1454. :2
  1455. ]
  1456. for field_name, related_model in (
  1457. (source_field_name, source),
  1458. (target_field_name, target),
  1459. ):
  1460. possible_field_names = []
  1461. for f in through._meta.fields:
  1462. if (
  1463. hasattr(f, "remote_field")
  1464. and getattr(f.remote_field, "model", None) == related_model
  1465. ):
  1466. possible_field_names.append(f.name)
  1467. if possible_field_names:
  1468. hint = (
  1469. "Did you mean one of the following foreign keys to '%s': "
  1470. "%s?"
  1471. % (
  1472. related_model._meta.object_name,
  1473. ", ".join(possible_field_names),
  1474. )
  1475. )
  1476. else:
  1477. hint = None
  1478. try:
  1479. field = through._meta.get_field(field_name)
  1480. except exceptions.FieldDoesNotExist:
  1481. errors.append(
  1482. checks.Error(
  1483. "The intermediary model '%s' has no field '%s'."
  1484. % (qualified_model_name, field_name),
  1485. hint=hint,
  1486. obj=self,
  1487. id="fields.E338",
  1488. )
  1489. )
  1490. else:
  1491. if not (
  1492. hasattr(field, "remote_field")
  1493. and getattr(field.remote_field, "model", None)
  1494. == related_model
  1495. ):
  1496. errors.append(
  1497. checks.Error(
  1498. "'%s.%s' is not a foreign key to '%s'."
  1499. % (
  1500. through._meta.object_name,
  1501. field_name,
  1502. related_model._meta.object_name,
  1503. ),
  1504. hint=hint,
  1505. obj=self,
  1506. id="fields.E339",
  1507. )
  1508. )
  1509. return errors
  1510. def _check_table_uniqueness(self, **kwargs):
  1511. if (
  1512. isinstance(self.remote_field.through, str)
  1513. or not self.remote_field.through._meta.managed
  1514. ):
  1515. return []
  1516. registered_tables = {
  1517. model._meta.db_table: model
  1518. for model in self.opts.apps.get_models(include_auto_created=True)
  1519. if model != self.remote_field.through and model._meta.managed
  1520. }
  1521. m2m_db_table = self.m2m_db_table()
  1522. model = registered_tables.get(m2m_db_table)
  1523. # The second condition allows multiple m2m relations on a model if
  1524. # some point to a through model that proxies another through model.
  1525. if (
  1526. model
  1527. and model._meta.concrete_model
  1528. != self.remote_field.through._meta.concrete_model
  1529. ):
  1530. if model._meta.auto_created:
  1531. def _get_field_name(model):
  1532. for field in model._meta.auto_created._meta.many_to_many:
  1533. if field.remote_field.through is model:
  1534. return field.name
  1535. opts = model._meta.auto_created._meta
  1536. clashing_obj = "%s.%s" % (opts.label, _get_field_name(model))
  1537. else:
  1538. clashing_obj = model._meta.label
  1539. if settings.DATABASE_ROUTERS:
  1540. error_class, error_id = checks.Warning, "fields.W344"
  1541. error_hint = (
  1542. "You have configured settings.DATABASE_ROUTERS. Verify "
  1543. "that the table of %r is correctly routed to a separate "
  1544. "database." % clashing_obj
  1545. )
  1546. else:
  1547. error_class, error_id = checks.Error, "fields.E340"
  1548. error_hint = None
  1549. return [
  1550. error_class(
  1551. "The field's intermediary table '%s' clashes with the "
  1552. "table name of '%s'." % (m2m_db_table, clashing_obj),
  1553. obj=self,
  1554. hint=error_hint,
  1555. id=error_id,
  1556. )
  1557. ]
  1558. return []
  1559. def deconstruct(self):
  1560. name, path, args, kwargs = super().deconstruct()
  1561. # Handle the simpler arguments.
  1562. if self.db_table is not None:
  1563. kwargs["db_table"] = self.db_table
  1564. if self.remote_field.db_constraint is not True:
  1565. kwargs["db_constraint"] = self.remote_field.db_constraint
  1566. # Lowercase model names as they should be treated as case-insensitive.
  1567. if isinstance(self.remote_field.model, str):
  1568. if "." in self.remote_field.model:
  1569. app_label, model_name = self.remote_field.model.split(".")
  1570. kwargs["to"] = "%s.%s" % (app_label, model_name.lower())
  1571. else:
  1572. kwargs["to"] = self.remote_field.model.lower()
  1573. else:
  1574. kwargs["to"] = self.remote_field.model._meta.label_lower
  1575. if getattr(self.remote_field, "through", None) is not None:
  1576. if isinstance(self.remote_field.through, str):
  1577. kwargs["through"] = self.remote_field.through
  1578. elif not self.remote_field.through._meta.auto_created:
  1579. kwargs["through"] = self.remote_field.through._meta.label
  1580. # If swappable is True, then see if we're actually pointing to the target
  1581. # of a swap.
  1582. swappable_setting = self.swappable_setting
  1583. if swappable_setting is not None:
  1584. # If it's already a settings reference, error.
  1585. if hasattr(kwargs["to"], "setting_name"):
  1586. if kwargs["to"].setting_name != swappable_setting:
  1587. raise ValueError(
  1588. "Cannot deconstruct a ManyToManyField pointing to a "
  1589. "model that is swapped in place of more than one model "
  1590. "(%s and %s)" % (kwargs["to"].setting_name, swappable_setting)
  1591. )
  1592. kwargs["to"] = SettingsReference(
  1593. kwargs["to"],
  1594. swappable_setting,
  1595. )
  1596. return name, path, args, kwargs
  1597. def _get_path_info(self, direct=False, filtered_relation=None):
  1598. """Called by both direct and indirect m2m traversal."""
  1599. int_model = self.remote_field.through
  1600. linkfield1 = int_model._meta.get_field(self.m2m_field_name())
  1601. linkfield2 = int_model._meta.get_field(self.m2m_reverse_field_name())
  1602. if direct:
  1603. join1infos = linkfield1.reverse_path_infos
  1604. if filtered_relation:
  1605. join2infos = linkfield2.get_path_info(filtered_relation)
  1606. else:
  1607. join2infos = linkfield2.path_infos
  1608. else:
  1609. join1infos = linkfield2.reverse_path_infos
  1610. if filtered_relation:
  1611. join2infos = linkfield1.get_path_info(filtered_relation)
  1612. else:
  1613. join2infos = linkfield1.path_infos
  1614. # Get join infos between the last model of join 1 and the first model
  1615. # of join 2. Assume the only reason these may differ is due to model
  1616. # inheritance.
  1617. join1_final = join1infos[-1].to_opts
  1618. join2_initial = join2infos[0].from_opts
  1619. if join1_final is join2_initial:
  1620. intermediate_infos = []
  1621. elif issubclass(join1_final.model, join2_initial.model):
  1622. intermediate_infos = join1_final.get_path_to_parent(join2_initial.model)
  1623. else:
  1624. intermediate_infos = join2_initial.get_path_from_parent(join1_final.model)
  1625. return [*join1infos, *intermediate_infos, *join2infos]
  1626. def get_path_info(self, filtered_relation=None):
  1627. return self._get_path_info(direct=True, filtered_relation=filtered_relation)
  1628. @cached_property
  1629. def path_infos(self):
  1630. return self.get_path_info()
  1631. def get_reverse_path_info(self, filtered_relation=None):
  1632. return self._get_path_info(direct=False, filtered_relation=filtered_relation)
  1633. @cached_property
  1634. def reverse_path_infos(self):
  1635. return self.get_reverse_path_info()
  1636. def _get_m2m_db_table(self, opts):
  1637. """
  1638. Function that can be curried to provide the m2m table name for this
  1639. relation.
  1640. """
  1641. if self.remote_field.through is not None:
  1642. return self.remote_field.through._meta.db_table
  1643. elif self.db_table:
  1644. return self.db_table
  1645. else:
  1646. m2m_table_name = "%s_%s" % (utils.strip_quotes(opts.db_table), self.name)
  1647. return utils.truncate_name(m2m_table_name, connection.ops.max_name_length())
  1648. def _get_m2m_attr(self, related, attr):
  1649. """
  1650. Function that can be curried to provide the source accessor or DB
  1651. column name for the m2m table.
  1652. """
  1653. cache_attr = "_m2m_%s_cache" % attr
  1654. if hasattr(self, cache_attr):
  1655. return getattr(self, cache_attr)
  1656. if self.remote_field.through_fields is not None:
  1657. link_field_name = self.remote_field.through_fields[0]
  1658. else:
  1659. link_field_name = None
  1660. for f in self.remote_field.through._meta.fields:
  1661. if (
  1662. f.is_relation
  1663. and f.remote_field.model == related.related_model
  1664. and (link_field_name is None or link_field_name == f.name)
  1665. ):
  1666. setattr(self, cache_attr, getattr(f, attr))
  1667. return getattr(self, cache_attr)
  1668. def _get_m2m_reverse_attr(self, related, attr):
  1669. """
  1670. Function that can be curried to provide the related accessor or DB
  1671. column name for the m2m table.
  1672. """
  1673. cache_attr = "_m2m_reverse_%s_cache" % attr
  1674. if hasattr(self, cache_attr):
  1675. return getattr(self, cache_attr)
  1676. found = False
  1677. if self.remote_field.through_fields is not None:
  1678. link_field_name = self.remote_field.through_fields[1]
  1679. else:
  1680. link_field_name = None
  1681. for f in self.remote_field.through._meta.fields:
  1682. if f.is_relation and f.remote_field.model == related.model:
  1683. if link_field_name is None and related.related_model == related.model:
  1684. # If this is an m2m-intermediate to self,
  1685. # the first foreign key you find will be
  1686. # the source column. Keep searching for
  1687. # the second foreign key.
  1688. if found:
  1689. setattr(self, cache_attr, getattr(f, attr))
  1690. break
  1691. else:
  1692. found = True
  1693. elif link_field_name is None or link_field_name == f.name:
  1694. setattr(self, cache_attr, getattr(f, attr))
  1695. break
  1696. return getattr(self, cache_attr)
  1697. def contribute_to_class(self, cls, name, **kwargs):
  1698. # To support multiple relations to self, it's useful to have a non-None
  1699. # related name on symmetrical relations for internal reasons. The
  1700. # concept doesn't make a lot of sense externally ("you want me to
  1701. # specify *what* on my non-reversible relation?!"), so we set it up
  1702. # automatically. The funky name reduces the chance of an accidental
  1703. # clash.
  1704. if self.remote_field.symmetrical and (
  1705. self.remote_field.model == RECURSIVE_RELATIONSHIP_CONSTANT
  1706. or self.remote_field.model == cls._meta.object_name
  1707. ):
  1708. self.remote_field.related_name = "%s_rel_+" % name
  1709. elif self.remote_field.is_hidden():
  1710. # If the backwards relation is disabled, replace the original
  1711. # related_name with one generated from the m2m field name. Django
  1712. # still uses backwards relations internally and we need to avoid
  1713. # clashes between multiple m2m fields with related_name == '+'.
  1714. self.remote_field.related_name = "_%s_%s_%s_+" % (
  1715. cls._meta.app_label,
  1716. cls.__name__.lower(),
  1717. name,
  1718. )
  1719. super().contribute_to_class(cls, name, **kwargs)
  1720. # The intermediate m2m model is not auto created if:
  1721. # 1) There is a manually specified intermediate, or
  1722. # 2) The class owning the m2m field is abstract.
  1723. # 3) The class owning the m2m field has been swapped out.
  1724. if not cls._meta.abstract:
  1725. if self.remote_field.through:
  1726. def resolve_through_model(_, model, field):
  1727. field.remote_field.through = model
  1728. lazy_related_operation(
  1729. resolve_through_model, cls, self.remote_field.through, field=self
  1730. )
  1731. elif not cls._meta.swapped:
  1732. self.remote_field.through = create_many_to_many_intermediary_model(
  1733. self, cls
  1734. )
  1735. # Add the descriptor for the m2m relation.
  1736. setattr(cls, self.name, ManyToManyDescriptor(self.remote_field, reverse=False))
  1737. # Set up the accessor for the m2m table name for the relation.
  1738. self.m2m_db_table = partial(self._get_m2m_db_table, cls._meta)
  1739. def contribute_to_related_class(self, cls, related):
  1740. # Internal M2Ms (i.e., those with a related name ending with '+')
  1741. # and swapped models don't get a related descriptor.
  1742. if (
  1743. not self.remote_field.is_hidden()
  1744. and not related.related_model._meta.swapped
  1745. ):
  1746. setattr(
  1747. cls,
  1748. related.get_accessor_name(),
  1749. ManyToManyDescriptor(self.remote_field, reverse=True),
  1750. )
  1751. # Set up the accessors for the column names on the m2m table.
  1752. self.m2m_column_name = partial(self._get_m2m_attr, related, "column")
  1753. self.m2m_reverse_name = partial(self._get_m2m_reverse_attr, related, "column")
  1754. self.m2m_field_name = partial(self._get_m2m_attr, related, "name")
  1755. self.m2m_reverse_field_name = partial(
  1756. self._get_m2m_reverse_attr, related, "name"
  1757. )
  1758. get_m2m_rel = partial(self._get_m2m_attr, related, "remote_field")
  1759. self.m2m_target_field_name = lambda: get_m2m_rel().field_name
  1760. get_m2m_reverse_rel = partial(
  1761. self._get_m2m_reverse_attr, related, "remote_field"
  1762. )
  1763. self.m2m_reverse_target_field_name = lambda: get_m2m_reverse_rel().field_name
  1764. def set_attributes_from_rel(self):
  1765. pass
  1766. def value_from_object(self, obj):
  1767. return [] if obj.pk is None else list(getattr(obj, self.attname).all())
  1768. def save_form_data(self, instance, data):
  1769. getattr(instance, self.attname).set(data)
  1770. def formfield(self, *, using=None, **kwargs):
  1771. defaults = {
  1772. "form_class": forms.ModelMultipleChoiceField,
  1773. "queryset": self.remote_field.model._default_manager.using(using),
  1774. **kwargs,
  1775. }
  1776. # If initial is passed in, it's a list of related objects, but the
  1777. # MultipleChoiceField takes a list of IDs.
  1778. if defaults.get("initial") is not None:
  1779. initial = defaults["initial"]
  1780. if callable(initial):
  1781. initial = initial()
  1782. defaults["initial"] = [i.pk for i in initial]
  1783. return super().formfield(**defaults)
  1784. def db_check(self, connection):
  1785. return None
  1786. def db_type(self, connection):
  1787. # A ManyToManyField is not represented by a single column,
  1788. # so return None.
  1789. return None
  1790. def db_parameters(self, connection):
  1791. return {"type": None, "check": None}