o 3akb@sddlZddlmZddlmZddlmZmZddl m Z ddl m Z ddl mZddlmZmZdd lmZdd lmZdd lmZdd lmZd dlmZd ddZddZddZddZGdddZ GdddeZ!GdddeZ"GdddZ#dS)!N)contextmanager) AppConfig)Appsapps)settings)models)RECURSIVE_RELATIONSHIP_CONSTANT) DEFAULT_NAMESnormalize_together)make_model_tuple)cached_property) import_string)get_docs_version)InvalidBasesErrorcCsFt|tr|dd}t|dkrt|S||dfS|jj|jjfS)N.rr) isinstancestrsplitlentuple_meta app_label model_name)modelrrrs  z'_get_related_models..T)include_parentsinclude_hiddenN) __subclasses__setr get_fields is_relation related_modelrraddrappendproxyconcrete_model)mrelated_modelsrelated_fields_modelsfoptsrrr_get_related_modelss   r5cCsddt|DS)zq Return a list of typical (app_label, model_name) tuples for all related models for the given model. cSsh|] }|jj|jjfqSr)rrr)r"rel_modrrr 2sz,get_related_models_tuples..)r5rrrrget_related_models_tuples-sr9cCsjt}t|}|D] }|jj|jj}}||f|vrq |||f|t|q ||jj|jjfhS)a Return all models that have a direct or indirect relationship to the given model. Relationships are either defined by explicit relational fields, like ForeignKey, ManyToManyField or OneToOneField, or by inheriting from another model (a superclass is related to its subclasses, but not vice versa). Note, however, that a model inheriting from a concrete model is also related to its superclass through the implicit *_ptr OneToOneField on the subclass. )r(r5rrrr,extend)rseenqueuer6 rel_app_labelrel_model_namerrrget_related_models_recursive8s  r?c@seZdZdZdddZddZddZd d d Zd d d Zd!ddZ ddZ ddZ ddZ e ddZeddZeddZddZdS)" ProjectStatez Represent the entire project's overall state. This is the item that is passed around - do it here rather than at the app level so that cross-app FKs/etc. resolve properly. NcCs|pi|_|pg|_d|_dSNF)r real_apps is_delayed)selfrrBrrr__init__Us   zProjectState.__init__cCs:|j|j}}||j||f<d|jvr|||dSdSNr)r name_lowerr__dict__ reload_model)rD model_staterrrrr add_model[s  zProjectState.add_modelcCs6|j||f=d|jvr|j|||jdSdSrF)rrHrunregister_model clear_cacherDrrrrr remove_modelas  zProjectState.remove_modelFc Cs|rd|_t}z |j||}Wn tyYn w|r"t|}nt|}|j||f}t}|j D]}|j rR|j j t krAq5t|j|\} } || | fq5|||D](\} } z |j| | } Wn typYqZw|r{|t| qZ|t| qZ|||f|S)NT)rCr(r get_model LookupErrorr9r?rfieldsvaluesr* remote_fieldrrrr+r,lowerupdate) rDrrdelayr1 old_modelrJdirect_related_modelsfieldr=r> rel_modelrrr_find_reload_modelis@      zProjectState._find_reload_modelcCs*d|jvr||||}||dSdSrF)rHr\_reload)rDrrrWr1rrrrIs zProjectState.reload_modelTcCsDd|jvr t}|D]\}}|||||q ||dSdSrF)rHr(rVr\r])rDrrWr1rrrrr reload_modelss  zProjectState.reload_modelsc Cs|j|D] \}}|j||qWdn1swYg}|jjD]}|j|jf|vr8||q)|D]\}}z |j||f}Wn tyQYq;w||q;|j |dSN) r bulk_updaterL real_modelsrrGr-rKeyErrorrender_multiple)rDr1r=r>states_to_be_renderedrJrrrr]s$       zProjectState._reloadcCs@tdd|jD|jd}d|jvr|j|_|j|_|S)z*Return an exact copy of this ProjectState.cSi|] \}}||qSrclone)r"kvrrr z&ProjectState.clone..)rrBr)r@ritemsrBrHrrgrC)rD new_staterrrrgs  zProjectState.clonecCs$|jrd|jvr|jd=dSdSdSrF)rCrHrDrrrclear_delayed_apps_caches z%ProjectState.clear_delayed_apps_cachecCst|j|jSr_) StateAppsrBrrnrrrrszProjectState.appscCst|j|jdd|_|jS)NT)ignore_swappable)rprBrrrnrrr concrete_appsszProjectState.concrete_appscCs8i}|jddD]}t|}|||j|jf<q||S)z3Take an Apps and return a ProjectState matching it.T)include_swapped) get_models ModelState from_modelrrG)clsr app_modelsrrJrrr from_appss  zProjectState.from_appscCs |j|jkot|jt|jkSr_)rr(rBrDotherrrr__eq__s zProjectState.__eq__)NNF)T)__name__ __module__ __qualname____doc__rErKrOr\rIr^r]rgror rpropertyrr classmethodryr|rrrrr@Ns$   0      r@c@s eZdZdZddZddZdS) AppConfigStubzAStub of an AppConfig. Only provides a label and a dict of models.cCsd|_i|_||_||_dSr_)rrlabelname)rDrrrrrEs zAppConfigStub.__init__cCs|jj|j|_dSr_)r all_modelsrrrnrrr import_modelsszAppConfigStub.import_modelsN)r~rrrrErrrrrrs rcsNeZdZdZdfdd ZeddZddZd d Zd d Z d dZ Z S)rpzo Subclass of the global Apps registry class to better handle dynamic model additions and removals. Fc sg|_|D]}t|}|D] }|jtj|ddqqdd|D}ddtg||D}t |d|_ d|_ | g||jddlm} |r[ttjhnt} | || d } | rrtd d d | DdS) NT) exclude_relscSh|]}|jqSr)r)r"rJrrrr7z%StateApps.__init__..cSsg|]}t|qSr)r)r"rrrrr$z&StateApps.__init__..r)_check_lazy_references)ignore css|]}|jVqdSr_)msg)r"errorrrr sz%StateApps.__init__..)ra global_appsget_app_configrtr-rurvrSsortedsuperrE_lock ready_eventrcdjango.core.checks.model_checksrr rAUTH_USER_MODELr( ValueErrorjoin) rDrBrrqrappr app_labels app_configsrrerrors __class__rrrEs$     zStateApps.__init__ccs:|j}d|_z dVW||_|dS||_|wrA)readyrM)rDrrrrr`s  zStateApps.bulk_updatec Cs|sdS|F|}|rFg}|D]}z||Wqty(||Yqwt|t|kr:td|tf|}|s WddSWddS1sQwYdS)NzCannot resolve bases for %r This can happen if you are inheriting models from an app with migrations (e.g. contrib.auth) in an app with no migrations; see https://docs.djangoproject.com/en/%s/topics/migrations/#dependencies for more)r`renderrr-rr)rD model_statesunrendered_modelsnew_unrendered_modelsrrrrrc#s.  "zStateApps.render_multiplecCsHtgi}t|j|_t|j|_|jD]}||_q|j|_|S)z Return a clone of this registry.)rpcopydeepcopyrrrSrra)rDrg app_configrrrrg=s zStateApps.clonecCs`||j||jj<||jvrt||j|<||j|_||j|j|jj<|||dSr_) rrrrrrrdo_pending_operationsrM)rDrrrrrregister_modelIs    zStateApps.register_modelcCs6z|j||=|j|j|=WdStyYdSwr_)rrrrbrNrrrrLRs   zStateApps.unregister_modelr}) r~rrrrErr`rcrgrrL __classcell__rrrrrps    rpc@sleZdZdZdddZeddZeddd Zd d Z d d Z ddZ ddZ ddZ ddZddZdS)rua Represent a Django Model. Don't use the actual Model class as it's not designed to have its options changed - instead, mutate this one and then render it into a Model as required. Note that while you are allowed to mutate .fields, you are not allowed to mutate the Field instances inside there themselves - you must instead assign new ones, as these are not detached during a clone. Nc Cs||_||_t||_|pi|_|jdg|jdg|p#tjf|_|p(g|_ |j D].\}}t |dr>t d||j rMt |jdrMt d||jr]t |jjdr]t d|q/|jdD] }|jsnt d|qcdS) Nindexes constraintsrz7ModelState.fields cannot be bound to a model - "%s" is.rz_ModelState.fields cannot refer to a model class - "%s.to" does. Use a string reference instead.zdModelState.fields cannot refer to a model class - "%s.through" does. Use a string reference instead.zKIndexes passed to ModelState require a name attribute. %r doesn't have one.)rrdictrRoptions setdefaultrr!basesmanagersrlhasattrrr*r+ many_to_manyrTthrough) rDrrrRrrrrZindexrrrrEesF    zModelState.__init__cCs |jSr_)rrUrnrrrrGs zModelState.name_lowerFc s&g}jjD]7}t|ddr|rqt|tjrq|j}z |||fWqt y=}z t d|jj |fd}~ww|sljj D]'}|j}z |||fWqDt yk}z t d|jj |fd}~wwi}t D]j}|dvrwqp|jjvr|dkrjjd}tt|||<qp|dkrjjd} tt| ||<qp|dkrd d jjD} | D] } | js| q| |d<qp|d krd d jjD|d <qpjj|||<qp|rd D] } | |vr|| =qn|dddjjDvr|d=fddttfddd} tdd| D}tdd|Ds&tjf}g}t}d}jjD]J}|j|vr;q1|jrIt|}|n#|jusU|jurjt }|j!|_!|j|_|juri|}nq1|"|j||j|fq1|d|fgkrg}|jj#jj ||||S)z3Given a model, return a ModelState representing it.rTNz'Couldn't reconstruct field %s on %s: %sz+Couldn't reconstruct m2m field %s on %s: %s)rrunique_togetherindex_togetherrcSg|]}|qSrrf)r"idxrrrr$rz)ModelState.from_model..rcSrrrf)r"conrrrr$r)rrorder_with_respect_torcSrr)r)r"rZrrrr7rz(ModelState.from_model..cs@g}|jD]}t|dr|jjr||q||q|S)Nr) __bases__rrabstractr:r-)rrbase) flatten_basesrrrs   z,ModelState.from_model..flatten_basescs j|Sr_)__mro__r)xr8rrs z'ModelState.from_model..keycss&|]}t|dr |jjn|VqdS)rN)rr label_lowerr"rrrrrs  z(ModelState.from_model..css&|]}t|tpt|tjVqdSr_)rrr rr!rrrrrs$objects)$r local_fieldsgetattrrrOrderWrtrr-rg TypeErrorrlocal_many_to_many object_namer original_attrsr(r rset_name_with_modelrgetprivate_fieldsrranyr!ruse_in_migrationsr_set_creation_counter _base_manager_default_managerManagerrr,r)rwrrrRrZrerutitrrrflattened_basesrr manager_namesdefault_manager_shimmanager new_managerr)rrrrvs                zModelState.from_modelc cspt|jddd}|D])\}}|\}}}}}|r't|} || fVq t|} || |i|fVq dS)z-Deep-clone the managers using deconstruction.cSs |djS)Nr)creation_counter)rirrrrs z/ModelState.construct_managers..rN)rr deconstructr as_manager) rDsorted_managersmgr_namerr manager_pathqs_pathargskwargsqs_class manager_classrrrconstruct_managers s zModelState.construct_managerscCs.|j|j|jt|jt|j|jt|jdS)z(Return an exact copy of this ModelState.)rrrRrrr) rrrrrRrrlistrrnrrrrgszModelState.clonecs|jd|j}tdd|}ztfdd|jD}Wnty,td|jfwdd|jD}||d<d |d <| | t|j ||S) zACreate a Model object from our current state into the given apps.)rrMetarc3s(|]}t|tr|n|VqdSr_)rrrPrrrrr.s  z$ModelState.render..z(Cannot resolve one or more bases from %rcSrerrf)r"rrZrrrrj5rkz%ModelState.render..__fake__r) rrtyperrrQrrRrlrVrr)rDr meta_contentsmetarbodyrrrr's   zModelState.rendercC4|jdD] }|j|kr|Sqtd||jf)NrzNo index named %s on model %srrr)rDrrrrrget_index_by_name>  zModelState.get_index_by_namecCr)Nrz"No constraint named %s on model %sr)rDr constraintrrrget_constraint_by_nameDrz!ModelState.get_constraint_by_namecCsd|jj|j|jfS)Nz <%s: '%s.%s'>)rr~rrrnrrr__repr__JszModelState.__repr__cCs||j|jko=|j|jko=t|jt|jko=tddtt|jt|jDo=|j|jko=|j |j ko=|j |j kS)NcssD|]\\}}\}}||ko|dd|ddkVqdS)rN)r)r"k1f1k2f2rrrrRs & z$ModelState.__eq__..) rrrrRallziprrlrrrrzrrrr|Ms$       zModelState.__eq__)NNNr})r~rrrrEr rGrrvrrgrrrrr|rrrrruZs "    ru)r)$r contextlibr django.appsrdjango.apps.registryrrr django.confr django.dbrdjango.db.models.fields.relatedrdjango.db.models.optionsr r django.db.models.utilsr django.utils.functionalr django.utils.module_loadingr django.utils.versionr exceptionsrrr5r9r?r@rrprurrrrs,            g