create exception subclass used by modelbase below the exception is created in a way that allows it to be pickled assuming that the returned exception class will be added as an attribute to the attachedto class only call contributetoclass if it s bound metaclass for all models def newcls name bases attrs kwargs supernew super new also ensure initialization is only performed for subclasses of model excluding model class itself parents b for b in bases if isinstanceb modelbase if not parents return supernewcls name bases attrs create the class module attrs popmodule newattrs module module classcell attrs popclasscell none if classcell is not none newattrsclasscell classcell attrmeta attrs popmeta none pass all attrs without a djangospecific contributetoclass method to type new so that they re properly initialized i e setname contributableattrs for objname obj in attrs items if hascontributetoclassobj contributableattrsobjname obj else newattrsobjname obj newclass supernewcls name bases newattrs kwargs abstract getattrattrmeta abstract false meta attrmeta or getattrnewclass meta none basemeta getattrnewclass meta none applabel none look for an application configuration to attach the model to appconfig apps getcontainingappconfigmodule if getattrmeta applabel none is none if appconfig is none if not abstract raise runtimeerror model class s s doesn t declare an explicit applabel and isn t in an application in installedapps module name else applabel appconfig label newclass addtoclassmeta optionsmeta applabel if not abstract newclass addtoclass doesnotexist subclassexception doesnotexist tuple x doesnotexist for x in parents if hasattrx meta and not x meta abstract or objectdoesnotexist module attachedtonewclass newclass addtoclass multipleobjectsreturned subclassexception multipleobjectsreturned tuple x multipleobjectsreturned for x in parents if hasattrx meta and not x meta abstract or multipleobjectsreturned module attachedtonewclass if basemeta and not basemeta abstract nonabstract child classes inherit some attributes from their nonabstract parent unless an abc comes before it in the method resolution order if not hasattrmeta ordering newclass meta ordering basemeta ordering if not hasattrmeta getlatestby newclass meta getlatestby basemeta getlatestby isproxy newclass meta proxy if the model is a proxy ensure that the base class hasn t been swapped out if isproxy and basemeta and basemeta swapped raise typeerror s cannot proxy the swapped model s name basemeta swapped add remaining attributes those with a contributetoclass method to the class for objname obj in contributableattrs items newclass addtoclassobjname obj all the fields of any type declared on this model newfields chain newclass meta localfields newclass meta localmanytomany newclass meta privatefields fieldnames f name for f in newfields basic setup for proxy models if isproxy base none for parent in kls for kls in parents if hasattrkls meta if parent meta abstract if parent meta fields raise typeerror abstract base class containing model fields not permitted for proxy model s name else continue if base is none base parent elif parent meta concretemodel is not base meta concretemodel raise typeerror proxy model s has more than one nonabstract model base class name if base is none raise typeerror proxy model s has no nonabstract model base class name newclass meta setupproxybase newclass meta concretemodel base meta concretemodel else newclass meta concretemodel newclass collect the parent links for multitable inheritance parentlinks for base in reversednewclass parents conceptually equivalent to if base is model if not hasattrbase meta continue skip concrete parent classes if base newclass and not base meta abstract continue locate onetoonefield instances for field in base meta localfields if isinstancefield onetoonefield and field remotefield parentlink related resolverelationnewclass field remotefield model parentlinksmakemodeltuplerelated field track fields inherited from base models inheritedattributes set do the appropriate setup for any model parents for base in newclass mro if base not in parents or not hasattrbase meta things without meta aren t functional models so they re uninteresting parents inheritedattributes updatebase dict continue parentfields base meta localfields base meta localmanytomany if not base meta abstract check for clashes between locally declared fields and those on the base classes for field in parentfields if field name in fieldnames raise fielderror local field r in class r clashes with field of the same name from base class r field name name base name else inheritedattributes addfield name concrete classes base base meta concretemodel basekey makemodeltuplebase if basekey in parentlinks field parentlinksbasekey elif not isproxy attrname sptr base meta modelname field onetoonefield base ondeletecascade nameattrname autocreatedtrue parentlinktrue if attrname in fieldnames raise fielderror autogenerated field s in class r for parentlink to base class r clashes with declared field of the same name attrname name base name only add the ptr field if it s not already present e g migrations will already have it specified if not hasattrnewclass attrname newclass addtoclassattrname field else field none newclass meta parentsbase field else baseparents base meta parents copy add fields from abstract base class if it wasn t overridden for field in parentfields if field name not in fieldnames and field name not in newclass dict and field name not in inheritedattributes newfield copy deepcopyfield newclass addtoclassfield name newfield replace parent links defined on this base by the new field it will be appropriately resolved if required if field onetoone for parent parentlink in baseparents items if field parentlink baseparentsparent newfield pass any nonabstract parent classes onto child newclass meta parents updatebaseparents inherit private fields like genericforeignkey from the parent class for field in base meta privatefields if field name in fieldnames if not base meta abstract raise fielderror local field r in class r clashes with field of the same name from base class r field name name base name else field copy deepcopyfield if not base meta abstract field mtiinherited true newclass addtoclassfield name field copy indexes so that index names are unique when models extend an abstract model newclass meta indexes copy deepcopyidx for idx in newclass meta indexes if abstract abstract base models can t be instantiated and don t appear in the list of models for an app we do the final setup for them a little differently from normal models attrmeta abstract false newclass meta attrmeta return newclass newclass prepare newclass meta apps registermodelnewclass meta applabel newclass return newclass def addtoclasscls name value if hascontributetoclassvalue value contributetoclasscls name else setattrcls name value def preparecls defer creating accessors on the foreign class until it has been created and registered if remotefield is none we re ordering with respect to a genericforeignkey and don t know what the foreign class is we ll add those accessors later in contributetoclass give the class a docstring its definition set the name of meta indexes this can t be done in options contributetoclass because fields haven t been added to the model at that point store model instance state db none if true uniqueness validation checks will consider this a new unsaved object necessary for correct validation of new instances of objects with explicit nonauto pks this impacts validation only it has no effect on the actual save adding true fieldscache modelstatefieldscachedescriptor class modelaltersdata metaclassmodelbase def initself args kwargs alias some things as locals to avoid repeat global lookups cls self class opts self meta setattr setattr deferred deferred if opts abstract raise typeerrorabstract models cannot be instantiated preinit sendsendercls argsargs kwargskwargs set up the storage for instance state self state modelstate there is a rather weird disparity here if kwargs it s set then args overrides it it should be one or the other don t duplicate the work the reason for the kwargs check is that standard iterator passes in by args and instantiation for iteration is 33 faster if lenargs lenopts concretefields daft but matches old exception sans the err msg raise indexerrornumber of args exceeds number of fields if not kwargs fieldsiter iteropts concretefields the ordering of the zip calls matter zip throws stopiteration when an iter throws it so if the first iter throws it the second is not consumed we rely on this so don t change the order without changing the logic for val field in zipargs fieldsiter if val is deferred continue setattrself field attname val else slower kwargsready version fieldsiter iteropts fields for val field in zipargs fieldsiter if val is deferred continue setattrself field attname val if kwargs popfield name notprovided is not notprovided raise typeerror fcls qualname got both positional and fkeyword arguments for field field name now we re left with the unprocessed fields that must come from keywords or default for field in fieldsiter isrelatedobject false virtual field if field attname not in kwargs and field column is none or field generated continue if kwargs if isinstancefield remotefield foreignobjectrel try assume object instance was passed in relobj kwargs popfield name isrelatedobject true except keyerror try object instance wasn t passed in must be an id val kwargs popfield attname except keyerror val field getdefault else try val kwargs popfield attname except keyerror this is done with an exception rather than the default argument on pop because we don t want getdefault to be evaluated and then not used refs 12057 val field getdefault else val field getdefault if isrelatedobject if we are passed a related instance set it using the field name instead of field attname e g user instead of userid so that the object gets properly cached and type checked by the relatedobjectdescriptor if relobj is not deferred setattrself field name relobj else if val is not deferred setattrself field attname val if kwargs propertynames opts propertynames unexpected for prop value in kwargs items any remaining kwargs must correspond to properties or virtual fields if prop in propertynames if value is not deferred setattrself prop value else try opts getfieldprop except fielddoesnotexist unexpected prop else if value is not deferred setattrself prop value if unexpected unexpectednames joinreprn for n in unexpected raise typeerror fcls name got unexpected keyword arguments funexpectednames super init postinit sendsendercls instanceself classmethod def fromdbcls db fieldnames values if lenvalues lencls meta concretefields valuesiter itervalues values nextvaluesiter if f attname in fieldnames else deferred for f in cls meta concretefields new clsvalues new state adding false new state db db return new def reprself return s s self class name self def strself return s object s self class name self pk def eqself other if not isinstanceother model return notimplemented if self meta concretemodel other meta concretemodel return false mypk self pk if mypk is none return self is other return mypk other pk def hashself if self pk is none raise typeerrormodel instances without primary key value are unhashable return hashself pk def reduceself data self getstate datadjangoversionpicklekey django version classid self meta applabel self meta objectname return modelunpickle classid data def getstateself memoryview cannot be pickled so cast it to bytes and store separately return a set containing names of deferred fields for this instance reload field values from the database by default the reloading happens from the database this instance was loaded from or by the read router if this instance wasn t loaded from any database the using parameter will override the default fields can be used to specify which fields to reload the fields should be an iterable of field attnames if fields is none then all nondeferred fields are reloaded when accessing deferred fields of an instance the deferred loading of the field will call this method use provided fields if not set then reload all nondeferred fields this field wasn t refreshed skip ahead clear cached foreign keys clear cached relations clear cached private relations return the value of the field name for this instance if the field is a foreign key return the id value instead of the object if there s no field object with this name on the model return the model attribute s value used to serialize a field s value in the serializer or form output for example normally you would just access the attribute directly and not use this method save the current instance override this in a subclass if you want to control the saving process the forceinsert and forceupdate parameters can be used to insist that the save must be an sql insert or update or equivalent for nonsql backends respectively normally they should not be set if updatefields is empty skip the save we do also check for noop saves later on for inheritance cases this bailout is still needed for skipping signal sending if saving to the same database and this model is deferred then automatically do an updatefields save on the loaded fields handle the parts of saving which should be done only once per save yet need to be done in raw saves too this includes some sanity checks and signal sending the raw argument is telling savebase not to save any parent models and not to do any changes to the values before save this is used by fixture loading skip proxies but keep the origin as the proxy model a transaction isn t needed if one query is issued validate force insert only when parents are inserted store the database on which the object was saved once saved this is no longer a tobeadded instance signal that the save is complete save all the parents of cls using values from self meta cls meta inserted false if updatedparents is none updatedparents for parent field in meta parents items make sure the link fields are synced between parent and self if field and getattrself parent meta pk attname is none and getattrself field attname is not none setattrself parent meta pk attname getattrself field attname if parentupdated updatedparents getparent is none parentinserted self saveparents clsparent usingusing updatefieldsupdatefields forceinsertforceinsert updatedparentsupdatedparents updated self savetable clsparent usingusing updatefieldsupdatefields forceinsertparentinserted or issubclassparent forceinsert if not updated inserted true updatedparentsparent updated elif not parentupdated inserted true set the parent s pk value to self if field setattrself field attname self getpkvalparent meta since we didn t have an instance of the parent handy set attname directly bypassing the descriptor invalidate the related object cache in case it s been accidentally populated a fresh instance will be rebuilt from the database if necessary if field iscachedself field deletecachedvalueself return inserted def savetable self rawfalse clsnone forceinsertfalse forceupdatefalse usingnone updatefieldsnone meta cls meta nonpks f for f in meta localconcretefields if not f primarykey if updatefields nonpks f for f in nonpks if f name in updatefields or f attname in updatefields pkval self getpkvalmeta if pkval is none pkval meta pk getpkvalueonsaveself setattrself meta pk attname pkval pkset pkval is not none if not pkset and forceupdate or updatefields raise valueerrorcannot force an update in save with no primary key updated false skip an update when adding an instance and primary key has a default if not raw and not forceinsert and self state adding and meta pk default and meta pk default is not notprovided or meta pk dbdefault and meta pk dbdefault is not notprovided forceinsert true if possible try an update if that doesn t update anything do an insert if pkset and not forceinsert baseqs cls basemanager usingusing values f none getattrself f attname if raw else f presaveself false for f in nonpks forcedupdate updatefields or forceupdate updated self doupdate baseqs using pkval values updatefields forcedupdate if forceupdate and not updated raise databaseerrorforced update did not affect any rows if updatefields and not updated raise databaseerrorsave with updatefields did not affect any rows if not updated if meta orderwithrespectto if this is a model with an orderwithrespectto autopopulate the order field field meta orderwithrespectto filterargs field getfilterkwargsforobjectself self order cls basemanager usingusing filterfilterargs aggregate ordermaxcoalesce expressionwrapper maxorder value1 outputfieldintegerfield value0 ordermax fields f for f in meta localconcretefields if not f generated and pkset or f is not meta autofield returningfields meta dbreturningfields results self doinsert cls basemanager using fields returningfields raw if results for value field in zipresults0 returningfields setattrself field attname value return updated def doupdateself baseqs using pkval values updatefields forcedupdate filtered baseqs filterpkpkval if not values we can end up here when saving a model in inheritance chain where updatefields doesn t target any field in current model in that case we just say the update succeeded another case ending up here is a model with just pk in that case check that the pk still exists return updatefields is not none or filtered exists if self meta selectonsave and not forcedupdate return filtered exists and it may happen that the object is deleted from the db right after this check causing the subsequent update to return zero matching rows the same result can occur in some rare cases when the database returns zero despite the update being executed successfully a row is matched and updated in order to distinguish these two cases the object s existence in the database is again checked for if the update query returns 0 filtered updatevalues 0 or filtered exists return filtered updatevalues 0 def doinsertself manager using fields returningfields raw return manager insert self fieldsfields returningfieldsreturningfields usingusing rawraw def preparerelatedfieldsforsaveself operationname fieldsnone ensure that a model instance without a pk hasn t been assigned to a foreignkey genericforeignkey or onetoonefield on this model if the field is nullable allowing the save would result in silent data loss for field in self meta concretefields if fields and field not in fields continue if the related field isn t cached then an instance hasn t been assigned and there s no need to worry about this check if field isrelation and field iscachedself obj getattrself field name none if not obj continue a pk may have been assigned manually to a model instance not saved to the database or autogenerated in a case like uuidfield but we allow the save to proceed and rely on the database to raise an integrityerror if applicable if constraints aren t supported by the database there s the unavoidable risk of data corruption if obj pk is none remove the object from a related instance cache if not field remotefield multiple field remotefield deletecachedvalueobj raise valueerror s prohibited to prevent data loss due to unsaved related object s operationname field name elif getattrself field attname in field emptyvalues set related object if it has been saved after an assignment setattrself field name obj if the relationship s pktofield was changed clear the cached relationship if getattrobj field targetfield attname getattr self field attname field deletecachedvalueself genericforeignkeys are private for field in self meta privatefields if fields and field not in fields continue if field isrelation and field iscachedself and hasattrfield fkfield obj field getcachedvalueself defaultnone if obj and obj pk is none raise valueerror foperationname prohibited to prevent data loss due to funsaved related object field name def deleteself usingnone keepparentsfalse if self pk is none raise valueerror s object can t be deleted because its s attribute is set to none self meta objectname self meta pk attname using using or router dbforwriteself class instanceself collector collectorusingusing originself collector collectself keepparentskeepparents return collector delete delete altersdata true async def adeleteself usingnone keepparentsfalse return await synctoasyncself delete usingusing keepparentskeepparents adelete altersdata true def getfielddisplayself field value getattrself field attname choicesdict dictmakehashablefield flatchoices forcestr to coerce lazy strings return forcestr choicesdict getmakehashablevalue value stringsonlytrue def getnextorpreviousbyfieldself field isnext kwargs if not self pk raise valueerrorgetnextgetprevious cannot be used on unsaved objects op gt if isnext else lt order if isnext else param getattrself field attname q q createfield name param fpkop self pk connectorq and q q createq ffield nameop param connectorq or qs self class defaultmanager usingself state db filterkwargs filterq orderbyss order field name spk order try return qs0 except indexerror raise self doesnotexist s matching query does not exist self class meta objectname def getnextorpreviousinorderself isnext cachename sordercache isnext if not hasattrself cachename op gt if isnext else lt order order if isnext else order orderfield self meta orderwithrespectto filterargs orderfield getfilterkwargsforobjectself obj self class defaultmanager filterfilterargs filter orders op self class defaultmanager valuesorder filter self meta pk name self pk orderbyorder 1 get setattrself cachename obj return getattrself cachename def getfieldvaluemapself meta excludenone if exclude is none exclude set meta meta or self meta fieldmap field name valuegetattrself field attname field for field in meta localconcretefields if field name not in exclude if pk not in exclude fieldmappk valueself pk meta pk return fieldmap def preparedatabasesaveself field if self pk is none raise valueerror unsaved model instance r cannot be used in an orm query self return getattrself field remotefield getrelatedfield attname def cleanself pass def validateuniqueself excludenone uniquechecks datechecks self getuniquechecksexcludeexclude errors self performuniquechecksuniquechecks dateerrors self performdatechecksdatechecks for k v in dateerrors items errors setdefaultk extendv if errors raise validationerrorerrors def getuniquechecksself excludenone includemetaconstraintsfalse if exclude is none exclude set uniquechecks uniquetogethers self class self meta uniquetogether constraints if includemetaconstraints constraints self class self meta totaluniqueconstraints for parentclass in self meta getparentlist if parentclass meta uniquetogether uniquetogethers append parentclass parentclass meta uniquetogether if includemetaconstraints and parentclass meta totaluniqueconstraints constraints append parentclass parentclass meta totaluniqueconstraints for modelclass uniquetogether in uniquetogethers for check in uniquetogether if not anyname in exclude for name in check add the check if the field isn t excluded uniquechecks appendmodelclass tuplecheck if includemetaconstraints for modelclass modelconstraints in constraints for constraint in modelconstraints if not anyname in exclude for name in constraint fields uniquechecks appendmodelclass constraint fields these are checks for the uniquefordateyearmonth datechecks gather a list of checks for fields declared as unique and add them to the list of checks fieldswithclass self class self meta localfields for parentclass in self meta getparentlist fieldswithclass appendparentclass parentclass meta localfields for modelclass fields in fieldswithclass for f in fields name f name if name in exclude continue if f unique uniquechecks appendmodelclass name if f uniquefordate and f uniquefordate not in exclude datechecks appendmodelclass date name f uniquefordate if f uniqueforyear and f uniqueforyear not in exclude datechecks appendmodelclass year name f uniqueforyear if f uniqueformonth and f uniqueformonth not in exclude datechecks appendmodelclass month name f uniqueformonth return uniquechecks datechecks def performuniquechecksself uniquechecks errors for modelclass uniquecheck in uniquechecks try to look up an existing object with the same values as this object s values for all the unique field lookupkwargs for fieldname in uniquecheck f self meta getfieldfieldname lookupvalue getattrself f attname todo handle multiple backends with different feature flags if lookupvalue is none or lookupvalue and connection features interpretsemptystringsasnulls no value skip the lookup continue if f primarykey and not self state adding no need to check for unique primary key when editing continue lookupkwargsstrfieldname lookupvalue some fields were skipped no reason to do the check if lenuniquecheck lenlookupkwargs continue qs modelclass defaultmanager filterlookupkwargs exclude the current object from the query if we are editing an instance as opposed to creating a new one note that we need to use the pk as defined by modelclass not self pk these can be different fields because model inheritance allows single model to have effectively multiple primary keys refs 17615 modelclasspk self getpkvalmodelclass meta if not self state adding and modelclasspk is not none qs qs excludepkmodelclasspk if qs exists if lenuniquecheck 1 key uniquecheck0 else key nonfielderrors errors setdefaultkey append self uniqueerrormessagemodelclass uniquecheck return errors def performdatechecksself datechecks errors for modelclass lookuptype field uniquefor in datechecks lookupkwargs there s a ticket to add a date lookup we can remove this special case if that makes it s way in date getattrself uniquefor if date is none continue if lookuptype date lookupkwargssday uniquefor date day lookupkwargssmonth uniquefor date month lookupkwargssyear uniquefor date year else lookupkwargsss uniquefor lookuptype getattr date lookuptype lookupkwargsfield getattrself field qs modelclass defaultmanager filterlookupkwargs exclude the current object from the query if we are editing an instance as opposed to creating a new one if not self state adding and self pk is not none qs qs excludepkself pk if qs exists errors setdefaultfield append self dateerrormessagelookuptype field uniquefor return errors def dateerrormessageself lookuptype fieldname uniquefor opts self meta field opts getfieldfieldname return validationerror messagefield errormessagesuniquefordate codeuniquefordate params model self modelname capfirstopts verbosename lookuptype lookuptype field fieldname fieldlabel capfirstfield verbosename datefield uniquefor datefieldlabel capfirstopts getfielduniquefor verbosename def uniqueerrormessageself modelclass uniquecheck opts modelclass meta params model self modelclass modelclass modelname capfirstopts verbosename uniquecheck uniquecheck a unique field if lenuniquecheck 1 field opts getfielduniquecheck0 paramsfieldlabel capfirstfield verbosename return validationerror messagefield errormessagesunique codeunique paramsparams uniquetogether else fieldlabels capfirstopts getfieldf verbosename for f in uniquecheck paramsfieldlabels gettextlistfieldlabels and return validationerror messagemodelnames with this fieldlabelss already exists codeuniquetogether paramsparams def getconstraintsself constraints self class self meta constraints for parentclass in self meta getparentlist if parentclass meta constraints constraints appendparentclass parentclass meta constraints return constraints def validateconstraintsself excludenone constraints self getconstraints using router dbforwriteself class instanceself errors for modelclass modelconstraints in constraints for constraint in modelconstraints try constraint validatemodelclass self excludeexclude usingusing except validationerror as e if getattre code none unique and lenconstraint fields 1 errors setdefaultconstraint fields0 appende else errors e updateerrordicterrors if errors raise validationerrorerrors def fullcleanself excludenone validateuniquetrue validateconstraintstrue errors if exclude is none exclude set else exclude setexclude try self cleanfieldsexcludeexclude except validationerror as e errors e updateerrordicterrors form clean is run even if other validation fails so do the same with model clean for consistency try self clean except validationerror as e errors e updateerrordicterrors run unique checks but only for fields that passed validation if validateunique for name in errors if name nonfielderrors and name not in exclude exclude addname try self validateuniqueexcludeexclude except validationerror as e errors e updateerrordicterrors run constraints checks but only for fields that passed validation if validateconstraints for name in errors if name nonfielderrors and name not in exclude exclude addname try self validateconstraintsexcludeexclude except validationerror as e errors e updateerrordicterrors if errors raise validationerrorerrors def cleanfieldsself excludenone if exclude is none exclude set errors for f in self meta fields if f name in exclude continue skip validation for empty fields with blanktrue the developer is responsible for making sure they have a valid value rawvalue getattrself f attname if f blank and rawvalue in f emptyvalues continue try setattrself f attname f cleanrawvalue self except validationerror as e errorsf name e errorlist if errors raise validationerrorerrors classmethod def checkcls kwargs errors cls checkswappable cls checkmodel cls checkmanagerskwargs if not cls meta swapped databases kwargs getdatabases or errors cls checkfieldskwargs cls checkm2mthroughsamerelationship cls checklongcolumnnamesdatabases clasherrors cls checkidfield cls checkfieldnameclashes cls checkmodelnamedblookupclashes cls checkpropertynamerelatedfieldaccessorclashes cls checksingleprimarykey errors extendclasherrors if there are field name clashes hide consequent column name clashes if not clasherrors errors extendcls checkcolumnnameclashes errors cls checkuniquetogether cls checkindexesdatabases cls checkordering cls checkconstraintsdatabases cls checkdefaultpk cls checkdbtablecommentdatabases return errors classmethod def checkdefaultpkcls if not cls meta abstract and cls meta pk autocreated and inherited pks are checked in parents models not isinstancecls meta pk onetoonefield and cls meta pk remotefield parentlink and not settings isoverriddendefaultautofield and cls meta appconfig and not cls meta appconfig isdefaultautofieldoverridden return checks warning fautocreated primary key used when not defining a fprimary key type by default f settings defaultautofield hint fconfigure the defaultautofield setting or the fcls meta appconfig class qualname fdefaultautofield attribute to point to a subclass fof autofield e g django db models bigautofield objcls idmodels w042 return classmethod def checkdbtablecommentcls databases if not cls meta dbtablecomment return errors for db in databases if not router allowmigratemodeldb cls continue connection connectionsdb if not connection features supportscomments or supportscomments in cls meta requireddbfeatures errors append checks warning fconnection displayname does not support comments on ftables dbtablecomment objcls idmodels w046 return errors classmethod def checkswappablecls perform all manager checks errors for manager in cls meta managers errors extendmanager checkkwargs return errors classmethod def checkfieldscls kwargs check if no relationship model is used by more than one m2m field errors seenintermediarysignatures fields cls meta localmanytomany skip when the target model wasn t found fields f for f in fields if isinstancef remotefield model modelbase skip when the relationship model wasn t found fields f for f in fields if isinstancef remotefield through modelbase for f in fields signature f remotefield model cls f remotefield through f remotefield throughfields if signature in seenintermediarysignatures errors append checks error the model has two identical manytomany relations through the intermediate model s f remotefield through meta label objcls idmodels e003 else seenintermediarysignatures appendsignature return errors classmethod def checkidfieldcls fields is empty or consists of the invalid id field forbid field shadowing in multitable inheritance errors usedfields name or attname field check that multiinheritance doesn t cause field name shadowing for parent in cls meta getparentlist for f in parent meta localfields clash usedfields getf name or usedfields getf attname or none if clash errors append checks error the field s from parent model s clashes with the field s from parent model s clash name clash model meta f name f model meta objcls idmodels e005 usedfieldsf name f usedfieldsf attname f check that fields defined in the model don t clash with fields from parents including autogenerated fields like multitable inheritance child accessors for parent in cls meta getparentlist for f in parent meta getfields if f not in usedfields usedfieldsf name f check that parent links in diamondshaped mti models don t clash for parentlink in cls meta parents values if not parentlink continue clash usedfields getparentlink name or none if clash errors append checks error fthe field parentlink name clashes with the field f clash name from model clash model meta objcls idmodels e006 for f in cls meta localfields clash usedfields getf name or usedfields getf attname or none note that we may detect clash between userdefined nonunique field id and automatically added unique field id both defined at the same model this special case is considered in checkidfield and here we ignore it idconflict f name id and clash and clash name id and clash model cls if clash and not idconflict errors append checks error the field s clashes with the field s from model s f name clash name clash model meta objf idmodels e006 usedfieldsf name f usedfieldsf attname f return errors classmethod def checkcolumnnameclashescls store a list of column names which have already been used by other fields usedcolumnnames errors for f in cls meta localfields columnname f getattnamecolumn ensure the column name is not already in use if columnname and columnname in usedcolumnnames errors append checks error field s has column name s that is used by another field f name columnname hintspecify a dbcolumn for the field objcls idmodels e007 else usedcolumnnames appendcolumnname return errors classmethod def checkmodelnamedblookupclashescls errors modelname cls name if modelname startswith or modelname endswith errors append checks error the model name s cannot start or end with an underscore as it collides with the query lookup syntax modelname objcls idmodels e023 elif lookupsep in modelname errors append checks error the model name s cannot contain double underscores as it collides with the query lookup syntax modelname objcls idmodels e024 return errors classmethod def checkpropertynamerelatedfieldaccessorclashescls errors propertynames cls meta propertynames relatedfieldaccessors f getattname for f in cls meta getfieldsreversefalse if f isrelation and f relatedmodel is not none for accessor in relatedfieldaccessors if accessor in propertynames errors append checks error the property s clashes with a related field accessor accessor objcls idmodels e025 return errors classmethod def checksingleprimarykeycls errors if sum1 for f in cls meta localfields if f primarykey 1 errors append checks error the model cannot have more than one field with primarykeytrue objcls idmodels e026 return errors classmethod def checkuniquetogethercls check fields names and conditions of indexes errors references set for index in cls meta indexes index name can t start with an underscore or a number restricted for crossdatabase compatibility with oracle if index name0 or index name0 isdigit errors append checks error the index name s cannot start with an underscore or a number index name objcls idmodels e033 if lenindex name index maxnamelength errors append checks error the index name s cannot be longer than d characters index name index maxnamelength objcls idmodels e034 if index containsexpressions for expression in index expressions references update ref0 for ref in cls getexprreferencesexpression for db in databases if not router allowmigratemodeldb cls continue connection connectionsdb if not connection features supportspartialindexes or supportspartialindexes in cls meta requireddbfeatures and anyindex condition is not none for index in cls meta indexes errors append checks warning s does not support indexes with conditions connection displayname hint conditions will be ignored silence this warning if you don t care about it objcls idmodels w037 if not connection features supportscoveringindexes or supportscoveringindexes in cls meta requireddbfeatures and anyindex include for index in cls meta indexes errors append checks warning s does not support indexes with nonkey columns connection displayname hint nonkey columns will be ignored silence this warning if you don t care about it objcls idmodels w040 if not connection features supportsexpressionindexes or supportsexpressionindexes in cls meta requireddbfeatures and anyindex containsexpressions for index in cls meta indexes errors append checks warning s does not support indexes on expressions connection displayname hint an index won t be created silence this warning if you don t care about it objcls idmodels w043 fields field for index in cls meta indexes for field in index fieldsorders fields include for index in cls meta indexes for include in index include fields references errors extendcls checklocalfieldsfields indexes return errors classmethod def checklocalfieldscls fields option from django db import models in order to avoid hitting the relation tree prematurely we use our own fieldsmap instead of using getfield forwardfieldsmap for field in cls meta getfieldsreversefalse forwardfieldsmapfield name field if hasattrfield attname forwardfieldsmapfield attname field errors for fieldname in fields try field forwardfieldsmapfieldname except keyerror errors append checks error s refers to the nonexistent field s option fieldname objcls idmodels e012 else if isinstancefield remotefield models manytomanyrel errors append checks error s refers to a manytomanyfield s but manytomanyfields are not permitted in s option fieldname option objcls idmodels e013 elif field not in cls meta localfields errors append checks error s refers to field s which is not local to model s option fieldname cls meta objectname hintthis issue may be caused by multitable inheritance objcls idmodels e016 return errors classmethod def checkorderingcls if cls meta orderingclash return checks error ordering and orderwithrespectto cannot be used together objcls idmodels e021 if cls meta orderwithrespectto or not cls meta ordering return if not isinstancecls meta ordering list tuple return checks error ordering must be a tuple or list even if you want to order by only one field objcls idmodels e014 errors fields cls meta ordering skip expressions and fields fields f for f in fields if isinstancef str and f convert field to field fields f removeprefix for f in fields separate related fields and nonrelated fields fields relatedfields for f in fields if lookupsep in f relatedfields appendf else fields appendf fields fields check related fields for field in relatedfields cls cls fld none for part in field splitlookupsep try pk is an alias that won t be found by opts getfield if part pk fld cls meta pk else fld cls meta getfieldpart if fld isrelation cls fld pathinfos1 toopts model else cls none except fielddoesnotexist attributeerror if fld is none or fld gettransformpart is none and fld getlookuppart is none errors append checks error ordering refers to the nonexistent field related field or lookup s field objcls idmodels e015 skip ordering on pk this is always a valid orderby field but is an alias and therefore won t be found by opts getfield fields f for f in fields if f pk check for invalid or nonexistent fields in ordering invalidfields any field name that is not present in fieldnames does not exist also ordering by m2m fields is not allowed opts cls meta validfields set chain fromiterable f name f attname if not f autocreated and not f concrete else f field relatedqueryname for f in chainopts fields opts relatedobjects invalidfields extendfields validfields for invalidfield in invalidfields errors append checks error ordering refers to the nonexistent field related field or lookup s invalidfield objcls idmodels e015 return errors classmethod def checklongcolumnnamescls databases if not databases return errors allowedlen none dbalias none find the minimum max allowed length among all specified dbaliases for db in databases skip databases where the model won t be created if not router allowmigratemodeldb cls continue connection connectionsdb maxnamelength connection ops maxnamelength if maxnamelength is none or connection features truncatesnames continue else if allowedlen is none allowedlen maxnamelength dbalias db elif maxnamelength allowedlen allowedlen maxnamelength dbalias db if allowedlen is none return errors for f in cls meta localfields columnname f getattnamecolumn check if autogenerated name for the field is too long for the database if f dbcolumn is none and columnname is not none and lencolumnname allowedlen errors append checks error autogenerated column name too long for field s maximum length is s for database s columnname allowedlen dbalias hintset the column name manually using dbcolumn objcls idmodels e018 for f in cls meta localmanytomany skip nonexistent models if isinstancef remotefield through str continue check if autogenerated name for the m2m field is too long for the database for m2m in f remotefield through meta localfields relname m2m getattnamecolumn if m2m dbcolumn is none and relname is not none and lenrelname allowedlen errors append checks error autogenerated column name too long for m2m field s maximum length is s for database s relname allowedlen dbalias hint use through to create a separate model for m2m and then set columnname using dbcolumn objcls idmodels e019 return errors classmethod def getexprreferencescls expr if isinstanceexpr q for child in expr children if isinstancechild tuple lookup value child yield tuplelookup splitlookupsep yield from cls getexprreferencesvalue else yield from cls getexprreferenceschild elif isinstanceexpr f yield tupleexpr name splitlookupsep elif hasattrexpr getsourceexpressions for srcexpr in expr getsourceexpressions yield from cls getexprreferencessrcexpr classmethod def checkconstraintscls databases errors for db in databases if not router allowmigratemodeldb cls continue connection connectionsdb if not connection features supportstablecheckconstraints or supportstablecheckconstraints in cls meta requireddbfeatures and any isinstanceconstraint checkconstraint for constraint in cls meta constraints errors append checks warning s does not support check constraints connection displayname hint a constraint won t be created silence this warning if you don t care about it objcls idmodels w027 if not connection features supportspartialindexes or supportspartialindexes in cls meta requireddbfeatures and any isinstanceconstraint uniqueconstraint and constraint condition is not none for constraint in cls meta constraints errors append checks warning s does not support unique constraints with conditions connection displayname hint a constraint won t be created silence this warning if you don t care about it objcls idmodels w036 if not connection features supportsdeferrableuniqueconstraints or supportsdeferrableuniqueconstraints in cls meta requireddbfeatures and any isinstanceconstraint uniqueconstraint and constraint deferrable is not none for constraint in cls meta constraints errors append checks warning s does not support deferrable unique constraints connection displayname hint a constraint won t be created silence this warning if you don t care about it objcls idmodels w038 if not connection features supportscoveringindexes or supportscoveringindexes in cls meta requireddbfeatures and any isinstanceconstraint uniqueconstraint and constraint include for constraint in cls meta constraints errors append checks warning s does not support unique constraints with nonkey columns connection displayname hint a constraint won t be created silence this warning if you don t care about it objcls idmodels w039 if not connection features supportsexpressionindexes or supportsexpressionindexes in cls meta requireddbfeatures and any isinstanceconstraint uniqueconstraint and constraint containsexpressions for constraint in cls meta constraints errors append checks warning s does not support unique constraints on expressions connection displayname hint a constraint won t be created silence this warning if you don t care about it objcls idmodels w044 if not connection features supportsnullsdistinctuniqueconstraints or supportsnullsdistinctuniqueconstraints in cls meta requireddbfeatures and any isinstanceconstraint uniqueconstraint and constraint nullsdistinct is not none for constraint in cls meta constraints errors append checks warning s does not support unique constraints with nulls distinct connection displayname hint a constraint won t be created silence this warning if you don t care about it objcls idmodels w047 fields set chain fromiterable constraint fields constraint include for constraint in cls meta constraints if isinstanceconstraint uniqueconstraint references set for constraint in cls meta constraints if isinstanceconstraint uniqueconstraint if connection features supportspartialindexes or supportspartialindexes not in cls meta requireddbfeatures and isinstanceconstraint condition q references update cls getexprreferencesconstraint condition if connection features supportsexpressionindexes or supportsexpressionindexes not in cls meta requireddbfeatures and constraint containsexpressions for expression in constraint expressions references updatecls getexprreferencesexpression elif isinstanceconstraint checkconstraint if connection features supportstablecheckconstraints or supportstablecheckconstraints not in cls meta requireddbfeatures if isinstanceconstraint check q references update cls getexprreferencesconstraint check if any isinstanceexpr rawsql for expr in constraint check flatten errors append checks warning fcheck constraint constraint name r contains frawsql expression and won t be validated fduring the model fullclean hint silence this warning if you don t care about it objcls idmodels w045 for fieldname lookups in references pk is an alias that won t be found by opts getfield if fieldname pk fields addfieldname if not lookups if it has no lookups it cannot result in a join continue try if fieldname pk field cls meta pk else field cls meta getfieldfieldname if not field isrelation or field manytomany or field onetomany continue except fielddoesnotexist continue join must happen at the first lookup firstlookup lookups0 if hasattrfield gettransform and hasattrfield getlookup and field gettransformfirstlookup is none and field getlookupfirstlookup is none errors append checks error constraints refers to the joined field s lookupsep joinfieldname lookups objcls idmodels e041 errors extendcls checklocalfieldsfields constraints return errors helper functions curried model methods ordering methods def methodsetorderself orderedobj idlist usingnone orderwrt orderedobj meta orderwithrespectto filterargs orderwrt getforwardrelatedfilterself orderedobj objects dbmanagerusing filterfilterargs bulkupdate orderedobjpkpk orderorder for order pk in enumerateidlist order def methodgetorderself orderedobj orderwrt orderedobj meta orderwithrespectto filterargs orderwrt getforwardrelatedfilterself pkname orderedobj meta pk name return orderedobj objects filterfilterargs valueslistpkname flattrue def makeforeignorderaccessorsmodel relatedmodel setattr relatedmodel getsorder model name lower partialmethodmethodgetorder model setattr relatedmodel setsorder model name lower partialmethodmethodsetorder model misc def modelunpicklemodelid backwards compat the model was cached directly in earlier versions create exception subclass used by modelbase below the exception is created in a way that allows it to be pickled assuming that the returned exception class will be added as an attribute to the attached_to class only call contribute_to_class if it s bound metaclass for all models also ensure initialization is only performed for subclasses of model excluding model class itself create the class pass all attrs without a django specific contribute_to_class method to type __new__ so that they re properly initialized i e __set_name__ look for an application configuration to attach the model to non abstract child classes inherit some attributes from their non abstract parent unless an abc comes before it in the method resolution order if the model is a proxy ensure that the base class hasn t been swapped out add remaining attributes those with a contribute_to_class method to the class all the fields of any type declared on this model basic setup for proxy models collect the parent links for multi table inheritance conceptually equivalent to if base is model skip concrete parent classes locate onetoonefield instances track fields inherited from base models do the appropriate setup for any model parents things without _meta aren t functional models so they re uninteresting parents check for clashes between locally declared fields and those on the base classes concrete classes only add the ptr field if it s not already present e g migrations will already have it specified add fields from abstract base class if it wasn t overridden replace parent links defined on this base by the new field it will be appropriately resolved if required pass any non abstract parent classes onto child inherit private fields like genericforeignkey from the parent class copy indexes so that index names are unique when models extend an abstract model abstract base models can t be instantiated and don t appear in the list of models for an app we do the final setup for them a little differently from normal models create some methods once self _meta has been populated defer creating accessors on the foreign class until it has been created and registered if remote_field is none we re ordering with respect to a genericforeignkey and don t know what the foreign class is we ll add those accessors later in contribute_to_class give the class a docstring its definition set the name of _meta indexes this can t be done in options contribute_to_class because fields haven t been added to the model at that point store model instance state if true uniqueness validation checks will consider this a new unsaved object necessary for correct validation of new instances of objects with explicit non auto pks this impacts validation only it has no effect on the actual save alias some things as locals to avoid repeat global lookups set up the storage for instance state there is a rather weird disparity here if kwargs it s set then args overrides it it should be one or the other don t duplicate the work the reason for the kwargs check is that standard iterator passes in by args and instantiation for iteration is 33 faster daft but matches old exception sans the err msg the ordering of the zip calls matter zip throws stopiteration when an iter throws it so if the first iter throws it the second is not consumed we rely on this so don t change the order without changing the logic slower kwargs ready version now we re left with the unprocessed fields that must come from keywords or default virtual field assume object instance was passed in object instance wasn t passed in must be an id this is done with an exception rather than the default argument on pop because we don t want get_default to be evaluated and then not used refs 12057 if we are passed a related instance set it using the field name instead of field attname e g user instead of user_id so that the object gets properly cached and type checked by the relatedobjectdescriptor any remaining kwargs must correspond to properties or virtual fields hook to allow choosing the attributes to pickle memoryview cannot be pickled so cast it to bytes and store separately return a set containing names of deferred fields for this instance reload field values from the database by default the reloading happens from the database this instance was loaded from or by the read router if this instance wasn t loaded from any database the using parameter will override the default fields can be used to specify which fields to reload the fields should be an iterable of field attnames if fields is none then all non deferred fields are reloaded when accessing deferred fields of an instance the deferred loading of the field will call this method use provided fields if not set then reload all non deferred fields this field wasn t refreshed skip ahead clear cached foreign keys clear cached relations clear cached private relations return the value of the field name for this instance if the field is a foreign key return the id value instead of the object if there s no field object with this name on the model return the model attribute s value used to serialize a field s value in the serializer or form output for example normally you would just access the attribute directly and not use this method save the current instance override this in a subclass if you want to control the saving process the force_insert and force_update parameters can be used to insist that the save must be an sql insert or update or equivalent for non sql backends respectively normally they should not be set if update_fields is empty skip the save we do also check for no op saves later on for inheritance cases this bailout is still needed for skipping signal sending if saving to the same database and this model is deferred then automatically do an update_fields save on the loaded fields handle the parts of saving which should be done only once per save yet need to be done in raw saves too this includes some sanity checks and signal sending the raw argument is telling save_base not to save any parent models and not to do any changes to the values before save this is used by fixture loading skip proxies but keep the origin as the proxy model a transaction isn t needed if one query is issued validate force insert only when parents are inserted store the database on which the object was saved once saved this is no longer a to be added instance signal that the save is complete save all the parents of cls using values from self make sure the link fields are synced between parent and self set the parent s pk value to self since we didn t have an instance of the parent handy set attname directly bypassing the descriptor invalidate the related object cache in case it s been accidentally populated a fresh instance will be re built from the database if necessary do the heavy lifting involved in saving update or insert the data for a single table skip an update when adding an instance and primary key has a default if possible try an update if that doesn t update anything do an insert if this is a model with an order_with_respect_to autopopulate the _order field try to update the model return true if the model was updated if an update query was done and a matching row was found in the db we can end up here when saving a model in inheritance chain where update_fields doesn t target any field in current model in that case we just say the update succeeded another case ending up here is a model with just pk in that case check that the pk still exists it may happen that the object is deleted from the db right after this check causing the subsequent update to return zero matching rows the same result can occur in some rare cases when the database returns zero despite the update being executed successfully a row is matched and updated in order to distinguish these two cases the object s existence in the database is again checked for if the update query returns 0 do an insert if returning_fields is defined then this method should return the newly created data for the model ensure that a model instance without a pk hasn t been assigned to a foreignkey genericforeignkey or onetoonefield on this model if the field is nullable allowing the save would result in silent data loss if the related field isn t cached then an instance hasn t been assigned and there s no need to worry about this check a pk may have been assigned manually to a model instance not saved to the database or auto generated in a case like uuidfield but we allow the save to proceed and rely on the database to raise an integrityerror if applicable if constraints aren t supported by the database there s the unavoidable risk of data corruption remove the object from a related instance cache set related object if it has been saved after an assignment if the relationship s pk to_field was changed clear the cached relationship genericforeignkeys are private force_str to coerce lazy strings hook for doing any extra model wide validation after clean has been called on every field by self clean_fields any validationerror raised by this method will not be associated with a particular field it will have a special case association with the field defined by non_field_errors check unique constraints on the model and raise validationerror if any failed return a list of checks to perform since validate_unique could be called from a modelform some fields may have been excluded we can t perform a unique check on a model that is missing fields involved in that check fields that did not validate should also be excluded but they need to be passed in via the exclude argument add the check if the field isn t excluded these are checks for the unique_for_ date year month gather a list of checks for fields declared as unique and add them to the list of checks try to look up an existing object with the same values as this object s values for all the unique field todo handle multiple backends with different feature flags no value skip the lookup no need to check for unique primary key when editing some fields were skipped no reason to do the check exclude the current object from the query if we are editing an instance as opposed to creating a new one note that we need to use the pk as defined by model_class not self pk these can be different fields because model inheritance allows single model to have effectively multiple primary keys refs 17615 there s a ticket to add a date lookup we can remove this special case if that makes it s way in exclude the current object from the query if we are editing an instance as opposed to creating a new one a unique field unique_together call clean_fields clean validate_unique and validate_constraints on the model raise a validationerror for any errors that occur form clean is run even if other validation fails so do the same with model clean for consistency run unique checks but only for fields that passed validation run constraints checks but only for fields that passed validation clean all fields and raise a validationerror containing a dict of all validation errors if any occur skip validation for empty fields with blank true the developer is responsible for making sure they have a valid value if there are field name clashes hide consequent column name clashes inherited pks are checked in parents models check if the swapped model exists perform all manager checks perform all field checks check if no relationship model is used by more than one m2m field skip when the target model wasn t found skip when the relationship model wasn t found check if id field is a primary key fields is empty or consists of the invalid id field forbid field shadowing in multi table inheritance name or attname field check that multi inheritance doesn t cause field name shadowing check that fields defined in the model don t clash with fields from parents including auto generated fields like multi table inheritance child accessors check that parent links in diamond shaped mti models don t clash note that we may detect clash between user defined non unique field id and automatically added unique field id both defined at the same model this special case is considered in _check_id_field and here we ignore it store a list of column names which have already been used by other fields ensure the column name is not already in use check the value of unique_together option check fields names and conditions of indexes index name can t start with an underscore or a number restricted for cross database compatibility with oracle in order to avoid hitting the relation tree prematurely we use our own fields_map instead of using get_field check ordering option is it a list of strings and do all fields exist skip expressions and fields convert field to field separate related fields and non related fields check related fields pk is an alias that won t be found by opts get_field skip ordering on pk this is always a valid order_by field but is an alias and therefore won t be found by opts get_field check for invalid or nonexistent fields in ordering any field name that is not present in field_names does not exist also ordering by m2m fields is not allowed check that any auto generated column names are shorter than the limits for each database in which the model will be created find the minimum max allowed length among all specified db_aliases skip databases where the model won t be created check if auto generated name for the field is too long for the database skip nonexistent models check if auto generated name for the m2m field is too long for the database pk is an alias that won t be found by opts get_field if it has no lookups it cannot result in a join join must happen at the first lookup helper functions curried model methods ordering methods misc used to unpickle model subclasses with deferred fields backwards compat the model was cached directly in earlier versions
import copy
import inspect
import warnings
from functools import partialmethod
from itertools import chain

from asgiref.sync import sync_to_async

import django
from django.apps import apps
from django.conf import settings
from django.core import checks
from django.core.exceptions import (
    NON_FIELD_ERRORS,
    FieldDoesNotExist,
    FieldError,
    MultipleObjectsReturned,
    ObjectDoesNotExist,
    ValidationError,
)
from django.db import (
    DJANGO_VERSION_PICKLE_KEY,
    DatabaseError,
    connection,
    connections,
    router,
    transaction,
)
from django.db.models import NOT_PROVIDED, ExpressionWrapper, IntegerField, Max, Value
from django.db.models.constants import LOOKUP_SEP
from django.db.models.constraints import CheckConstraint, UniqueConstraint
from django.db.models.deletion import CASCADE, Collector
from django.db.models.expressions import RawSQL
from django.db.models.fields.related import (
    ForeignObjectRel,
    OneToOneField,
    lazy_related_operation,
    resolve_relation,
)
from django.db.models.functions import Coalesce
from django.db.models.manager import Manager
from django.db.models.options import Options
from django.db.models.query import F, Q
from django.db.models.signals import (
    class_prepared,
    post_init,
    post_save,
    pre_init,
    pre_save,
)
from django.db.models.utils import AltersData, make_model_tuple
from django.utils.encoding import force_str
from django.utils.hashable import make_hashable
from django.utils.text import capfirst, get_text_list
from django.utils.translation import gettext_lazy as _


class Deferred:
    def __repr__(self):
        return "<Deferred field>"

    def __str__(self):
        return "<Deferred field>"


DEFERRED = Deferred()


def subclass_exception(name, bases, module, attached_to):
    
    return type(
        name,
        bases,
        {
            "__module__": module,
            "__qualname__": "%s.%s" % (attached_to.__qualname__, name),
        },
    )


def _has_contribute_to_class(value):
    
    return not inspect.isclass(value) and hasattr(value, "contribute_to_class")


class ModelBase(type):
    

    def __new__(cls, name, bases, attrs, **kwargs):
        super_new = super().__new__

        
        
        parents = [b for b in bases if isinstance(b, ModelBase)]
        if not parents:
            return super_new(cls, name, bases, attrs)

        
        module = attrs.pop("__module__")
        new_attrs = {"__module__": module}
        classcell = attrs.pop("__classcell__", None)
        if classcell is not None:
            new_attrs["__classcell__"] = classcell
        attr_meta = attrs.pop("Meta", None)
        
        
        
        contributable_attrs = {}
        for obj_name, obj in attrs.items():
            if _has_contribute_to_class(obj):
                contributable_attrs[obj_name] = obj
            else:
                new_attrs[obj_name] = obj
        new_class = super_new(cls, name, bases, new_attrs, **kwargs)

        abstract = getattr(attr_meta, "abstract", False)
        meta = attr_meta or getattr(new_class, "Meta", None)
        base_meta = getattr(new_class, "_meta", None)

        app_label = None

        
        app_config = apps.get_containing_app_config(module)

        if getattr(meta, "app_label", None) is None:
            if app_config is None:
                if not abstract:
                    raise RuntimeError(
                        "Model class %s.%s doesn't declare an explicit "
                        "app_label and isn't in an application in "
                        "INSTALLED_APPS." % (module, name)
                    )

            else:
                app_label = app_config.label

        new_class.add_to_class("_meta", Options(meta, app_label))
        if not abstract:
            new_class.add_to_class(
                "DoesNotExist",
                subclass_exception(
                    "DoesNotExist",
                    tuple(
                        x.DoesNotExist
                        for x in parents
                        if hasattr(x, "_meta") and not x._meta.abstract
                    )
                    or (ObjectDoesNotExist,),
                    module,
                    attached_to=new_class,
                ),
            )
            new_class.add_to_class(
                "MultipleObjectsReturned",
                subclass_exception(
                    "MultipleObjectsReturned",
                    tuple(
                        x.MultipleObjectsReturned
                        for x in parents
                        if hasattr(x, "_meta") and not x._meta.abstract
                    )
                    or (MultipleObjectsReturned,),
                    module,
                    attached_to=new_class,
                ),
            )
            if base_meta and not base_meta.abstract:
                
                
                
                if not hasattr(meta, "ordering"):
                    new_class._meta.ordering = base_meta.ordering
                if not hasattr(meta, "get_latest_by"):
                    new_class._meta.get_latest_by = base_meta.get_latest_by

        is_proxy = new_class._meta.proxy

        
        
        if is_proxy and base_meta and base_meta.swapped:
            raise TypeError(
                "%s cannot proxy the swapped model '%s'." % (name, base_meta.swapped)
            )

        
        
        for obj_name, obj in contributable_attrs.items():
            new_class.add_to_class(obj_name, obj)

        
        new_fields = chain(
            new_class._meta.local_fields,
            new_class._meta.local_many_to_many,
            new_class._meta.private_fields,
        )
        field_names = {f.name for f in new_fields}

        
        if is_proxy:
            base = None
            for parent in [kls for kls in parents if hasattr(kls, "_meta")]:
                if parent._meta.abstract:
                    if parent._meta.fields:
                        raise TypeError(
                            "Abstract base class containing model fields not "
                            "permitted for proxy model '%s'." % name
                        )
                    else:
                        continue
                if base is None:
                    base = parent
                elif parent._meta.concrete_model is not base._meta.concrete_model:
                    raise TypeError(
                        "Proxy model '%s' has more than one non-abstract model base "
                        "class." % name
                    )
            if base is None:
                raise TypeError(
                    "Proxy model '%s' has no non-abstract model base class." % name
                )
            new_class._meta.setup_proxy(base)
            new_class._meta.concrete_model = base._meta.concrete_model
        else:
            new_class._meta.concrete_model = new_class

        
        parent_links = {}
        for base in reversed([new_class] + parents):
            
            if not hasattr(base, "_meta"):
                continue
            
            if base != new_class and not base._meta.abstract:
                continue
            
            for field in base._meta.local_fields:
                if isinstance(field, OneToOneField) and field.remote_field.parent_link:
                    related = resolve_relation(new_class, field.remote_field.model)
                    parent_links[make_model_tuple(related)] = field

        
        inherited_attributes = set()
        
        for base in new_class.mro():
            if base not in parents or not hasattr(base, "_meta"):
                
                
                inherited_attributes.update(base.__dict__)
                continue

            parent_fields = base._meta.local_fields + base._meta.local_many_to_many
            if not base._meta.abstract:
                
                
                for field in parent_fields:
                    if field.name in field_names:
                        raise FieldError(
                            "Local field %r in class %r clashes with field of "
                            "the same name from base class %r."
                            % (
                                field.name,
                                name,
                                base.__name__,
                            )
                        )
                    else:
                        inherited_attributes.add(field.name)

                
                base = base._meta.concrete_model
                base_key = make_model_tuple(base)
                if base_key in parent_links:
                    field = parent_links[base_key]
                elif not is_proxy:
                    attr_name = "%s_ptr" % base._meta.model_name
                    field = OneToOneField(
                        base,
                        on_delete=CASCADE,
                        name=attr_name,
                        auto_created=True,
                        parent_link=True,
                    )

                    if attr_name in field_names:
                        raise FieldError(
                            "Auto-generated field '%s' in class %r for "
                            "parent_link to base class %r clashes with "
                            "declared field of the same name."
                            % (
                                attr_name,
                                name,
                                base.__name__,
                            )
                        )

                    
                    
                    if not hasattr(new_class, attr_name):
                        new_class.add_to_class(attr_name, field)
                else:
                    field = None
                new_class._meta.parents[base] = field
            else:
                base_parents = base._meta.parents.copy()

                
                for field in parent_fields:
                    if (
                        field.name not in field_names
                        and field.name not in new_class.__dict__
                        and field.name not in inherited_attributes
                    ):
                        new_field = copy.deepcopy(field)
                        new_class.add_to_class(field.name, new_field)
                        
                        
                        if field.one_to_one:
                            for parent, parent_link in base_parents.items():
                                if field == parent_link:
                                    base_parents[parent] = new_field

                
                new_class._meta.parents.update(base_parents)

            
            
            for field in base._meta.private_fields:
                if field.name in field_names:
                    if not base._meta.abstract:
                        raise FieldError(
                            "Local field %r in class %r clashes with field of "
                            "the same name from base class %r."
                            % (
                                field.name,
                                name,
                                base.__name__,
                            )
                        )
                else:
                    field = copy.deepcopy(field)
                    if not base._meta.abstract:
                        field.mti_inherited = True
                    new_class.add_to_class(field.name, field)

        
        
        new_class._meta.indexes = [
            copy.deepcopy(idx) for idx in new_class._meta.indexes
        ]

        if abstract:
            
            
            
            attr_meta.abstract = False
            new_class.Meta = attr_meta
            return new_class

        new_class._prepare()
        new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
        return new_class

    def add_to_class(cls, name, value):
        if _has_contribute_to_class(value):
            value.contribute_to_class(cls, name)
        else:
            setattr(cls, name, value)

    def _prepare(cls):
        
        opts = cls._meta
        opts._prepare(cls)

        if opts.order_with_respect_to:
            cls.get_next_in_order = partialmethod(
                cls._get_next_or_previous_in_order, is_next=True
            )
            cls.get_previous_in_order = partialmethod(
                cls._get_next_or_previous_in_order, is_next=False
            )

            
            
            
            
            
            if opts.order_with_respect_to.remote_field:
                wrt = opts.order_with_respect_to
                remote = wrt.remote_field.model
                lazy_related_operation(make_foreign_order_accessors, cls, remote)

        
        if cls.__doc__ is None:
            cls.__doc__ = "%s(%s)" % (
                cls.__name__,
                ", ".join(f.name for f in opts.fields),
            )

        get_absolute_url_override = settings.ABSOLUTE_URL_OVERRIDES.get(
            opts.label_lower
        )
        if get_absolute_url_override:
            setattr(cls, "get_absolute_url", get_absolute_url_override)

        if not opts.managers:
            if any(f.name == "objects" for f in opts.fields):
                raise ValueError(
                    "Model %s must specify a custom Manager, because it has a "
                    "field named 'objects'." % cls.__name__
                )
            manager = Manager()
            manager.auto_created = True
            cls.add_to_class("objects", manager)

        
        
        
        for index in cls._meta.indexes:
            if not index.name:
                index.set_name_with_model(cls)

        class_prepared.send(sender=cls)

    @property
    def _base_manager(cls):
        return cls._meta.base_manager

    @property
    def _default_manager(cls):
        return cls._meta.default_manager


class ModelStateFieldsCacheDescriptor:
    def __get__(self, instance, cls=None):
        if instance is None:
            return self
        res = instance.fields_cache = {}
        return res


class ModelState:
    

    db = None
    
    
    
    
    adding = True
    fields_cache = ModelStateFieldsCacheDescriptor()


class Model(AltersData, metaclass=ModelBase):
    def __init__(self, *args, **kwargs):
        
        cls = self.__class__
        opts = self._meta
        _setattr = setattr
        _DEFERRED = DEFERRED
        if opts.abstract:
            raise TypeError("Abstract models cannot be instantiated.")

        pre_init.send(sender=cls, args=args, kwargs=kwargs)

        
        self._state = ModelState()

        
        
        
        
        if len(args) > len(opts.concrete_fields):
            
            raise IndexError("Number of args exceeds number of fields")

        if not kwargs:
            fields_iter = iter(opts.concrete_fields)
            
            
            
            
            for val, field in zip(args, fields_iter):
                if val is _DEFERRED:
                    continue
                _setattr(self, field.attname, val)
        else:
            
            fields_iter = iter(opts.fields)
            for val, field in zip(args, fields_iter):
                if val is _DEFERRED:
                    continue
                _setattr(self, field.attname, val)
                if kwargs.pop(field.name, NOT_PROVIDED) is not NOT_PROVIDED:
                    raise TypeError(
                        f"{cls.__qualname__}() got both positional and "
                        f"keyword arguments for field '{field.name}'."
                    )

        
        

        for field in fields_iter:
            is_related_object = False
            
            if field.attname not in kwargs and field.column is None or field.generated:
                continue
            if kwargs:
                if isinstance(field.remote_field, ForeignObjectRel):
                    try:
                        
                        rel_obj = kwargs.pop(field.name)
                        is_related_object = True
                    except KeyError:
                        try:
                            
                            val = kwargs.pop(field.attname)
                        except KeyError:
                            val = field.get_default()
                else:
                    try:
                        val = kwargs.pop(field.attname)
                    except KeyError:
                        
                        
                        
                        
                        val = field.get_default()
            else:
                val = field.get_default()

            if is_related_object:
                
                
                
                
                if rel_obj is not _DEFERRED:
                    _setattr(self, field.name, rel_obj)
            else:
                if val is not _DEFERRED:
                    _setattr(self, field.attname, val)

        if kwargs:
            property_names = opts._property_names
            unexpected = ()
            for prop, value in kwargs.items():
                
                
                if prop in property_names:
                    if value is not _DEFERRED:
                        _setattr(self, prop, value)
                else:
                    try:
                        opts.get_field(prop)
                    except FieldDoesNotExist:
                        unexpected += (prop,)
                    else:
                        if value is not _DEFERRED:
                            _setattr(self, prop, value)
            if unexpected:
                unexpected_names = ", ".join(repr(n) for n in unexpected)
                raise TypeError(
                    f"{cls.__name__}() got unexpected keyword arguments: "
                    f"{unexpected_names}"
                )
        super().__init__()
        post_init.send(sender=cls, instance=self)

    @classmethod
    def from_db(cls, db, field_names, values):
        if len(values) != len(cls._meta.concrete_fields):
            values_iter = iter(values)
            values = [
                next(values_iter) if f.attname in field_names else DEFERRED
                for f in cls._meta.concrete_fields
            ]
        new = cls(*values)
        new._state.adding = False
        new._state.db = db
        return new

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self)

    def __str__(self):
        return "%s object (%s)" % (self.__class__.__name__, self.pk)

    def __eq__(self, other):
        if not isinstance(other, Model):
            return NotImplemented
        if self._meta.concrete_model != other._meta.concrete_model:
            return False
        my_pk = self.pk
        if my_pk is None:
            return self is other
        return my_pk == other.pk

    def __hash__(self):
        if self.pk is None:
            raise TypeError("Model instances without primary key value are unhashable")
        return hash(self.pk)

    def __reduce__(self):
        data = self.__getstate__()
        data[DJANGO_VERSION_PICKLE_KEY] = django.__version__
        class_id = self._meta.app_label, self._meta.object_name
        return model_unpickle, (class_id,), data

    def __getstate__(self):
        
        state = self.__dict__.copy()
        state["_state"] = copy.copy(state["_state"])
        state["_state"].fields_cache = state["_state"].fields_cache.copy()
        
        
        _memoryview_attrs = []
        for attr, value in state.items():
            if isinstance(value, memoryview):
                _memoryview_attrs.append((attr, bytes(value)))
        if _memoryview_attrs:
            state["_memoryview_attrs"] = _memoryview_attrs
            for attr, value in _memoryview_attrs:
                state.pop(attr)
        return state

    def __setstate__(self, state):
        pickled_version = state.get(DJANGO_VERSION_PICKLE_KEY)
        if pickled_version:
            if pickled_version != django.__version__:
                warnings.warn(
                    "Pickled model instance's Django version %s does not "
                    "match the current version %s."
                    % (pickled_version, django.__version__),
                    RuntimeWarning,
                    stacklevel=2,
                )
        else:
            warnings.warn(
                "Pickled model instance's Django version is not specified.",
                RuntimeWarning,
                stacklevel=2,
            )
        if "_memoryview_attrs" in state:
            for attr, value in state.pop("_memoryview_attrs"):
                state[attr] = memoryview(value)
        self.__dict__.update(state)

    def _get_pk_val(self, meta=None):
        meta = meta or self._meta
        return getattr(self, meta.pk.attname)

    def _set_pk_val(self, value):
        for parent_link in self._meta.parents.values():
            if parent_link and parent_link != self._meta.pk:
                setattr(self, parent_link.target_field.attname, value)
        return setattr(self, self._meta.pk.attname, value)

    pk = property(_get_pk_val, _set_pk_val)

    def get_deferred_fields(self):
        
        return {
            f.attname
            for f in self._meta.concrete_fields
            if f.attname not in self.__dict__
        }

    def refresh_from_db(self, using=None, fields=None):
        
        if fields is None:
            self._prefetched_objects_cache = {}
        else:
            prefetched_objects_cache = getattr(self, "_prefetched_objects_cache", ())
            fields = list(fields)
            for field in list(fields):
                if field in prefetched_objects_cache:
                    del prefetched_objects_cache[field]
                    fields.remove(field)
            if not fields:
                return
            if any(LOOKUP_SEP in f for f in fields):
                raise ValueError(
                    'Found "%s" in fields argument. Relations and transforms '
                    "are not allowed in fields." % LOOKUP_SEP
                )

        hints = {"instance": self}
        db_instance_qs = self.__class__._base_manager.db_manager(
            using, hints=hints
        ).filter(pk=self.pk)

        
        deferred_fields = self.get_deferred_fields()
        if fields is not None:
            db_instance_qs = db_instance_qs.only(*fields)
        elif deferred_fields:
            fields = [
                f.attname
                for f in self._meta.concrete_fields
                if f.attname not in deferred_fields
            ]
            db_instance_qs = db_instance_qs.only(*fields)

        db_instance = db_instance_qs.get()
        non_loaded_fields = db_instance.get_deferred_fields()
        for field in self._meta.concrete_fields:
            if field.attname in non_loaded_fields:
                
                continue
            setattr(self, field.attname, getattr(db_instance, field.attname))
            
            if field.is_relation and field.is_cached(self):
                field.delete_cached_value(self)

        
        for field in self._meta.related_objects:
            if field.is_cached(self):
                field.delete_cached_value(self)

        
        for field in self._meta.private_fields:
            if field.is_relation and field.is_cached(self):
                field.delete_cached_value(self)

        self._state.db = db_instance._state.db

    async def arefresh_from_db(self, using=None, fields=None):
        return await sync_to_async(self.refresh_from_db)(using=using, fields=fields)

    def serializable_value(self, field_name):
        
        try:
            field = self._meta.get_field(field_name)
        except FieldDoesNotExist:
            return getattr(self, field_name)
        return getattr(self, field.attname)

    def save(
        self, force_insert=False, force_update=False, using=None, update_fields=None
    ):
        
        self._prepare_related_fields_for_save(operation_name="save")

        using = using or router.db_for_write(self.__class__, instance=self)
        if force_insert and (force_update or update_fields):
            raise ValueError("Cannot force both insert and updating in model saving.")

        deferred_fields = self.get_deferred_fields()
        if update_fields is not None:
            
            
            
            if not update_fields:
                return

            update_fields = frozenset(update_fields)
            field_names = self._meta._non_pk_concrete_field_names
            non_model_fields = update_fields.difference(field_names)

            if non_model_fields:
                raise ValueError(
                    "The following fields do not exist in this model, are m2m "
                    "fields, or are non-concrete fields: %s"
                    % ", ".join(non_model_fields)
                )

        
        
        elif not force_insert and deferred_fields and using == self._state.db:
            field_names = set()
            for field in self._meta.concrete_fields:
                if not field.primary_key and not hasattr(field, "through"):
                    field_names.add(field.attname)
            loaded_fields = field_names.difference(deferred_fields)
            if loaded_fields:
                update_fields = frozenset(loaded_fields)

        self.save_base(
            using=using,
            force_insert=force_insert,
            force_update=force_update,
            update_fields=update_fields,
        )

    save.alters_data = True

    async def asave(
        self, force_insert=False, force_update=False, using=None, update_fields=None
    ):
        return await sync_to_async(self.save)(
            force_insert=force_insert,
            force_update=force_update,
            using=using,
            update_fields=update_fields,
        )

    asave.alters_data = True

    @classmethod
    def _validate_force_insert(cls, force_insert):
        if force_insert is False:
            return ()
        if force_insert is True:
            return (cls,)
        if not isinstance(force_insert, tuple):
            raise TypeError("force_insert must be a bool or tuple.")
        for member in force_insert:
            if not isinstance(member, ModelBase):
                raise TypeError(
                    f"Invalid force_insert member. {member!r} must be a model subclass."
                )
            if not issubclass(cls, member):
                raise TypeError(
                    f"Invalid force_insert member. {member.__qualname__} must be a "
                    f"base of {cls.__qualname__}."
                )
        return force_insert

    def save_base(
        self,
        raw=False,
        force_insert=False,
        force_update=False,
        using=None,
        update_fields=None,
    ):
        
        using = using or router.db_for_write(self.__class__, instance=self)
        assert not (force_insert and (force_update or update_fields))
        assert update_fields is None or update_fields
        cls = origin = self.__class__
        
        if cls._meta.proxy:
            cls = cls._meta.concrete_model
        meta = cls._meta
        if not meta.auto_created:
            pre_save.send(
                sender=origin,
                instance=self,
                raw=raw,
                using=using,
                update_fields=update_fields,
            )
        
        if meta.parents:
            context_manager = transaction.atomic(using=using, savepoint=False)
        else:
            context_manager = transaction.mark_for_rollback_on_error(using=using)
        with context_manager:
            parent_inserted = False
            if not raw:
                
                force_insert = self._validate_force_insert(force_insert)
                parent_inserted = self._save_parents(
                    cls, using, update_fields, force_insert
                )
            updated = self._save_table(
                raw,
                cls,
                force_insert or parent_inserted,
                force_update,
                using,
                update_fields,
            )
        
        self._state.db = using
        
        self._state.adding = False

        
        if not meta.auto_created:
            post_save.send(
                sender=origin,
                instance=self,
                created=(not updated),
                update_fields=update_fields,
                raw=raw,
                using=using,
            )

    save_base.alters_data = True

    def _save_parents(
        self, cls, using, update_fields, force_insert, updated_parents=None
    ):
        
        meta = cls._meta
        inserted = False
        if updated_parents is None:
            updated_parents = {}
        for parent, field in meta.parents.items():
            
            if (
                field
                and getattr(self, parent._meta.pk.attname) is None
                and getattr(self, field.attname) is not None
            ):
                setattr(self, parent._meta.pk.attname, getattr(self, field.attname))
            if (parent_updated := updated_parents.get(parent)) is None:
                parent_inserted = self._save_parents(
                    cls=parent,
                    using=using,
                    update_fields=update_fields,
                    force_insert=force_insert,
                    updated_parents=updated_parents,
                )
                updated = self._save_table(
                    cls=parent,
                    using=using,
                    update_fields=update_fields,
                    force_insert=parent_inserted or issubclass(parent, force_insert),
                )
                if not updated:
                    inserted = True
                updated_parents[parent] = updated
            elif not parent_updated:
                inserted = True
            
            if field:
                setattr(self, field.attname, self._get_pk_val(parent._meta))
                
                
                
                
                
                if field.is_cached(self):
                    field.delete_cached_value(self)
        return inserted

    def _save_table(
        self,
        raw=False,
        cls=None,
        force_insert=False,
        force_update=False,
        using=None,
        update_fields=None,
    ):
        
        meta = cls._meta
        non_pks = [f for f in meta.local_concrete_fields if not f.primary_key]

        if update_fields:
            non_pks = [
                f
                for f in non_pks
                if f.name in update_fields or f.attname in update_fields
            ]

        pk_val = self._get_pk_val(meta)
        if pk_val is None:
            pk_val = meta.pk.get_pk_value_on_save(self)
            setattr(self, meta.pk.attname, pk_val)
        pk_set = pk_val is not None
        if not pk_set and (force_update or update_fields):
            raise ValueError("Cannot force an update in save() with no primary key.")
        updated = False
        
        if (
            not raw
            and not force_insert
            and self._state.adding
            and (
                (meta.pk.default and meta.pk.default is not NOT_PROVIDED)
                or (meta.pk.db_default and meta.pk.db_default is not NOT_PROVIDED)
            )
        ):
            force_insert = True
        
        if pk_set and not force_insert:
            base_qs = cls._base_manager.using(using)
            values = [
                (
                    f,
                    None,
                    (getattr(self, f.attname) if raw else f.pre_save(self, False)),
                )
                for f in non_pks
            ]
            forced_update = update_fields or force_update
            updated = self._do_update(
                base_qs, using, pk_val, values, update_fields, forced_update
            )
            if force_update and not updated:
                raise DatabaseError("Forced update did not affect any rows.")
            if update_fields and not updated:
                raise DatabaseError("Save with update_fields did not affect any rows.")
        if not updated:
            if meta.order_with_respect_to:
                
                
                field = meta.order_with_respect_to
                filter_args = field.get_filter_kwargs_for_object(self)
                self._order = (
                    cls._base_manager.using(using)
                    .filter(**filter_args)
                    .aggregate(
                        _order__max=Coalesce(
                            ExpressionWrapper(
                                Max("_order") + Value(1), output_field=IntegerField()
                            ),
                            Value(0),
                        ),
                    )["_order__max"]
                )
            fields = [
                f
                for f in meta.local_concrete_fields
                if not f.generated and (pk_set or f is not meta.auto_field)
            ]
            returning_fields = meta.db_returning_fields
            results = self._do_insert(
                cls._base_manager, using, fields, returning_fields, raw
            )
            if results:
                for value, field in zip(results[0], returning_fields):
                    setattr(self, field.attname, value)
        return updated

    def _do_update(self, base_qs, using, pk_val, values, update_fields, forced_update):
        
        filtered = base_qs.filter(pk=pk_val)
        if not values:
            
            
            
            
            
            return update_fields is not None or filtered.exists()
        if self._meta.select_on_save and not forced_update:
            return (
                filtered.exists()
                and
                
                
                
                
                
                
                
                (filtered._update(values) > 0 or filtered.exists())
            )
        return filtered._update(values) > 0

    def _do_insert(self, manager, using, fields, returning_fields, raw):
        
        return manager._insert(
            [self],
            fields=fields,
            returning_fields=returning_fields,
            using=using,
            raw=raw,
        )

    def _prepare_related_fields_for_save(self, operation_name, fields=None):
        
        
        
        
        for field in self._meta.concrete_fields:
            if fields and field not in fields:
                continue
            
            
            if field.is_relation and field.is_cached(self):
                obj = getattr(self, field.name, None)
                if not obj:
                    continue
                
                
                
                
                
                
                if obj.pk is None:
                    
                    if not field.remote_field.multiple:
                        field.remote_field.delete_cached_value(obj)
                    raise ValueError(
                        "%s() prohibited to prevent data loss due to unsaved "
                        "related object '%s'." % (operation_name, field.name)
                    )
                elif getattr(self, field.attname) in field.empty_values:
                    
                    
                    setattr(self, field.name, obj)
                
                
                if getattr(obj, field.target_field.attname) != getattr(
                    self, field.attname
                ):
                    field.delete_cached_value(self)
        
        for field in self._meta.private_fields:
            if fields and field not in fields:
                continue
            if (
                field.is_relation
                and field.is_cached(self)
                and hasattr(field, "fk_field")
            ):
                obj = field.get_cached_value(self, default=None)
                if obj and obj.pk is None:
                    raise ValueError(
                        f"{operation_name}() prohibited to prevent data loss due to "
                        f"unsaved related object '{field.name}'."
                    )

    def delete(self, using=None, keep_parents=False):
        if self.pk is None:
            raise ValueError(
                "%s object can't be deleted because its %s attribute is set "
                "to None." % (self._meta.object_name, self._meta.pk.attname)
            )
        using = using or router.db_for_write(self.__class__, instance=self)
        collector = Collector(using=using, origin=self)
        collector.collect([self], keep_parents=keep_parents)
        return collector.delete()

    delete.alters_data = True

    async def adelete(self, using=None, keep_parents=False):
        return await sync_to_async(self.delete)(
            using=using,
            keep_parents=keep_parents,
        )

    adelete.alters_data = True

    def _get_FIELD_display(self, field):
        value = getattr(self, field.attname)
        choices_dict = dict(make_hashable(field.flatchoices))
        
        return force_str(
            choices_dict.get(make_hashable(value), value), strings_only=True
        )

    def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs):
        if not self.pk:
            raise ValueError("get_next/get_previous cannot be used on unsaved objects.")
        op = "gt" if is_next else "lt"
        order = "" if is_next else "-"
        param = getattr(self, field.attname)
        q = Q.create([(field.name, param), (f"pk__{op}", self.pk)], connector=Q.AND)
        q = Q.create([q, (f"{field.name}__{op}", param)], connector=Q.OR)
        qs = (
            self.__class__._default_manager.using(self._state.db)
            .filter(**kwargs)
            .filter(q)
            .order_by("%s%s" % (order, field.name), "%spk" % order)
        )
        try:
            return qs[0]
        except IndexError:
            raise self.DoesNotExist(
                "%s matching query does not exist." % self.__class__._meta.object_name
            )

    def _get_next_or_previous_in_order(self, is_next):
        cachename = "__%s_order_cache" % is_next
        if not hasattr(self, cachename):
            op = "gt" if is_next else "lt"
            order = "_order" if is_next else "-_order"
            order_field = self._meta.order_with_respect_to
            filter_args = order_field.get_filter_kwargs_for_object(self)
            obj = (
                self.__class__._default_manager.filter(**filter_args)
                .filter(
                    **{
                        "_order__%s"
                        % op: self.__class__._default_manager.values("_order").filter(
                            **{self._meta.pk.name: self.pk}
                        )
                    }
                )
                .order_by(order)[:1]
                .get()
            )
            setattr(self, cachename, obj)
        return getattr(self, cachename)

    def _get_field_value_map(self, meta, exclude=None):
        if exclude is None:
            exclude = set()
        meta = meta or self._meta
        field_map = {
            field.name: Value(getattr(self, field.attname), field)
            for field in meta.local_concrete_fields
            if field.name not in exclude
        }
        if "pk" not in exclude:
            field_map["pk"] = Value(self.pk, meta.pk)
        return field_map

    def prepare_database_save(self, field):
        if self.pk is None:
            raise ValueError(
                "Unsaved model instance %r cannot be used in an ORM query." % self
            )
        return getattr(self, field.remote_field.get_related_field().attname)

    def clean(self):
        
        pass

    def validate_unique(self, exclude=None):
        
        unique_checks, date_checks = self._get_unique_checks(exclude=exclude)

        errors = self._perform_unique_checks(unique_checks)
        date_errors = self._perform_date_checks(date_checks)

        for k, v in date_errors.items():
            errors.setdefault(k, []).extend(v)

        if errors:
            raise ValidationError(errors)

    def _get_unique_checks(self, exclude=None, include_meta_constraints=False):
        
        if exclude is None:
            exclude = set()
        unique_checks = []

        unique_togethers = [(self.__class__, self._meta.unique_together)]
        constraints = []
        if include_meta_constraints:
            constraints = [(self.__class__, self._meta.total_unique_constraints)]
        for parent_class in self._meta.get_parent_list():
            if parent_class._meta.unique_together:
                unique_togethers.append(
                    (parent_class, parent_class._meta.unique_together)
                )
            if include_meta_constraints and parent_class._meta.total_unique_constraints:
                constraints.append(
                    (parent_class, parent_class._meta.total_unique_constraints)
                )

        for model_class, unique_together in unique_togethers:
            for check in unique_together:
                if not any(name in exclude for name in check):
                    
                    unique_checks.append((model_class, tuple(check)))

        if include_meta_constraints:
            for model_class, model_constraints in constraints:
                for constraint in model_constraints:
                    if not any(name in exclude for name in constraint.fields):
                        unique_checks.append((model_class, constraint.fields))

        
        date_checks = []

        
        

        fields_with_class = [(self.__class__, self._meta.local_fields)]
        for parent_class in self._meta.get_parent_list():
            fields_with_class.append((parent_class, parent_class._meta.local_fields))

        for model_class, fields in fields_with_class:
            for f in fields:
                name = f.name
                if name in exclude:
                    continue
                if f.unique:
                    unique_checks.append((model_class, (name,)))
                if f.unique_for_date and f.unique_for_date not in exclude:
                    date_checks.append((model_class, "date", name, f.unique_for_date))
                if f.unique_for_year and f.unique_for_year not in exclude:
                    date_checks.append((model_class, "year", name, f.unique_for_year))
                if f.unique_for_month and f.unique_for_month not in exclude:
                    date_checks.append((model_class, "month", name, f.unique_for_month))
        return unique_checks, date_checks

    def _perform_unique_checks(self, unique_checks):
        errors = {}

        for model_class, unique_check in unique_checks:
            
            

            lookup_kwargs = {}
            for field_name in unique_check:
                f = self._meta.get_field(field_name)
                lookup_value = getattr(self, f.attname)
                
                if lookup_value is None or (
                    lookup_value == ""
                    and connection.features.interprets_empty_strings_as_nulls
                ):
                    
                    continue
                if f.primary_key and not self._state.adding:
                    
                    continue
                lookup_kwargs[str(field_name)] = lookup_value

            
            if len(unique_check) != len(lookup_kwargs):
                continue

            qs = model_class._default_manager.filter(**lookup_kwargs)

            
            
            
            
            
            
            model_class_pk = self._get_pk_val(model_class._meta)
            if not self._state.adding and model_class_pk is not None:
                qs = qs.exclude(pk=model_class_pk)
            if qs.exists():
                if len(unique_check) == 1:
                    key = unique_check[0]
                else:
                    key = NON_FIELD_ERRORS
                errors.setdefault(key, []).append(
                    self.unique_error_message(model_class, unique_check)
                )

        return errors

    def _perform_date_checks(self, date_checks):
        errors = {}
        for model_class, lookup_type, field, unique_for in date_checks:
            lookup_kwargs = {}
            
            
            date = getattr(self, unique_for)
            if date is None:
                continue
            if lookup_type == "date":
                lookup_kwargs["%s__day" % unique_for] = date.day
                lookup_kwargs["%s__month" % unique_for] = date.month
                lookup_kwargs["%s__year" % unique_for] = date.year
            else:
                lookup_kwargs["%s__%s" % (unique_for, lookup_type)] = getattr(
                    date, lookup_type
                )
            lookup_kwargs[field] = getattr(self, field)

            qs = model_class._default_manager.filter(**lookup_kwargs)
            
            
            if not self._state.adding and self.pk is not None:
                qs = qs.exclude(pk=self.pk)

            if qs.exists():
                errors.setdefault(field, []).append(
                    self.date_error_message(lookup_type, field, unique_for)
                )
        return errors

    def date_error_message(self, lookup_type, field_name, unique_for):
        opts = self._meta
        field = opts.get_field(field_name)
        return ValidationError(
            message=field.error_messages["unique_for_date"],
            code="unique_for_date",
            params={
                "model": self,
                "model_name": capfirst(opts.verbose_name),
                "lookup_type": lookup_type,
                "field": field_name,
                "field_label": capfirst(field.verbose_name),
                "date_field": unique_for,
                "date_field_label": capfirst(opts.get_field(unique_for).verbose_name),
            },
        )

    def unique_error_message(self, model_class, unique_check):
        opts = model_class._meta

        params = {
            "model": self,
            "model_class": model_class,
            "model_name": capfirst(opts.verbose_name),
            "unique_check": unique_check,
        }

        
        if len(unique_check) == 1:
            field = opts.get_field(unique_check[0])
            params["field_label"] = capfirst(field.verbose_name)
            return ValidationError(
                message=field.error_messages["unique"],
                code="unique",
                params=params,
            )

        
        else:
            field_labels = [
                capfirst(opts.get_field(f).verbose_name) for f in unique_check
            ]
            params["field_labels"] = get_text_list(field_labels, _("and"))
            return ValidationError(
                message=_("%(model_name)s with this %(field_labels)s already exists."),
                code="unique_together",
                params=params,
            )

    def get_constraints(self):
        constraints = [(self.__class__, self._meta.constraints)]
        for parent_class in self._meta.get_parent_list():
            if parent_class._meta.constraints:
                constraints.append((parent_class, parent_class._meta.constraints))
        return constraints

    def validate_constraints(self, exclude=None):
        constraints = self.get_constraints()
        using = router.db_for_write(self.__class__, instance=self)

        errors = {}
        for model_class, model_constraints in constraints:
            for constraint in model_constraints:
                try:
                    constraint.validate(model_class, self, exclude=exclude, using=using)
                except ValidationError as e:
                    if (
                        getattr(e, "code", None) == "unique"
                        and len(constraint.fields) == 1
                    ):
                        errors.setdefault(constraint.fields[0], []).append(e)
                    else:
                        errors = e.update_error_dict(errors)
        if errors:
            raise ValidationError(errors)

    def full_clean(self, exclude=None, validate_unique=True, validate_constraints=True):
        
        errors = {}
        if exclude is None:
            exclude = set()
        else:
            exclude = set(exclude)

        try:
            self.clean_fields(exclude=exclude)
        except ValidationError as e:
            errors = e.update_error_dict(errors)

        
        
        try:
            self.clean()
        except ValidationError as e:
            errors = e.update_error_dict(errors)

        
        if validate_unique:
            for name in errors:
                if name != NON_FIELD_ERRORS and name not in exclude:
                    exclude.add(name)
            try:
                self.validate_unique(exclude=exclude)
            except ValidationError as e:
                errors = e.update_error_dict(errors)

        
        if validate_constraints:
            for name in errors:
                if name != NON_FIELD_ERRORS and name not in exclude:
                    exclude.add(name)
            try:
                self.validate_constraints(exclude=exclude)
            except ValidationError as e:
                errors = e.update_error_dict(errors)

        if errors:
            raise ValidationError(errors)

    def clean_fields(self, exclude=None):
        
        if exclude is None:
            exclude = set()

        errors = {}
        for f in self._meta.fields:
            if f.name in exclude:
                continue
            
            
            raw_value = getattr(self, f.attname)
            if f.blank and raw_value in f.empty_values:
                continue
            try:
                setattr(self, f.attname, f.clean(raw_value, self))
            except ValidationError as e:
                errors[f.name] = e.error_list

        if errors:
            raise ValidationError(errors)

    @classmethod
    def check(cls, **kwargs):
        errors = [
            *cls._check_swappable(),
            *cls._check_model(),
            *cls._check_managers(**kwargs),
        ]
        if not cls._meta.swapped:
            databases = kwargs.get("databases") or []
            errors += [
                *cls._check_fields(**kwargs),
                *cls._check_m2m_through_same_relationship(),
                *cls._check_long_column_names(databases),
            ]
            clash_errors = (
                *cls._check_id_field(),
                *cls._check_field_name_clashes(),
                *cls._check_model_name_db_lookup_clashes(),
                *cls._check_property_name_related_field_accessor_clashes(),
                *cls._check_single_primary_key(),
            )
            errors.extend(clash_errors)
            
            
            if not clash_errors:
                errors.extend(cls._check_column_name_clashes())
            errors += [
                *cls._check_unique_together(),
                *cls._check_indexes(databases),
                *cls._check_ordering(),
                *cls._check_constraints(databases),
                *cls._check_default_pk(),
                *cls._check_db_table_comment(databases),
            ]

        return errors

    @classmethod
    def _check_default_pk(cls):
        if (
            not cls._meta.abstract
            and cls._meta.pk.auto_created
            and
            
            not (
                isinstance(cls._meta.pk, OneToOneField)
                and cls._meta.pk.remote_field.parent_link
            )
            and not settings.is_overridden("DEFAULT_AUTO_FIELD")
            and cls._meta.app_config
            and not cls._meta.app_config._is_default_auto_field_overridden
        ):
            return [
                checks.Warning(
                    f"Auto-created primary key used when not defining a "
                    f"primary key type, by default "
                    f"'{settings.DEFAULT_AUTO_FIELD}'.",
                    hint=(
                        f"Configure the DEFAULT_AUTO_FIELD setting or the "
                        f"{cls._meta.app_config.__class__.__qualname__}."
                        f"default_auto_field attribute to point to a subclass "
                        f"of AutoField, e.g. 'django.db.models.BigAutoField'."
                    ),
                    obj=cls,
                    id="models.W042",
                ),
            ]
        return []

    @classmethod
    def _check_db_table_comment(cls, databases):
        if not cls._meta.db_table_comment:
            return []
        errors = []
        for db in databases:
            if not router.allow_migrate_model(db, cls):
                continue
            connection = connections[db]
            if not (
                connection.features.supports_comments
                or "supports_comments" in cls._meta.required_db_features
            ):
                errors.append(
                    checks.Warning(
                        f"{connection.display_name} does not support comments on "
                        f"tables (db_table_comment).",
                        obj=cls,
                        id="models.W046",
                    )
                )
        return errors

    @classmethod
    def _check_swappable(cls):
        
        errors = []
        if cls._meta.swapped:
            try:
                apps.get_model(cls._meta.swapped)
            except ValueError:
                errors.append(
                    checks.Error(
                        "'%s' is not of the form 'app_label.app_name'."
                        % cls._meta.swappable,
                        id="models.E001",
                    )
                )
            except LookupError:
                app_label, model_name = cls._meta.swapped.split(".")
                errors.append(
                    checks.Error(
                        "'%s' references '%s.%s', which has not been "
                        "installed, or is abstract."
                        % (cls._meta.swappable, app_label, model_name),
                        id="models.E002",
                    )
                )
        return errors

    @classmethod
    def _check_model(cls):
        errors = []
        if cls._meta.proxy:
            if cls._meta.local_fields or cls._meta.local_many_to_many:
                errors.append(
                    checks.Error(
                        "Proxy model '%s' contains model fields." % cls.__name__,
                        id="models.E017",
                    )
                )
        return errors

    @classmethod
    def _check_managers(cls, **kwargs):
        
        errors = []
        for manager in cls._meta.managers:
            errors.extend(manager.check(**kwargs))
        return errors

    @classmethod
    def _check_fields(cls, **kwargs):
        
        errors = []
        for field in cls._meta.local_fields:
            errors.extend(field.check(**kwargs))
        for field in cls._meta.local_many_to_many:
            errors.extend(field.check(from_model=cls, **kwargs))
        return errors

    @classmethod
    def _check_m2m_through_same_relationship(cls):
        

        errors = []
        seen_intermediary_signatures = []

        fields = cls._meta.local_many_to_many

        
        fields = (f for f in fields if isinstance(f.remote_field.model, ModelBase))

        
        fields = (f for f in fields if isinstance(f.remote_field.through, ModelBase))

        for f in fields:
            signature = (
                f.remote_field.model,
                cls,
                f.remote_field.through,
                f.remote_field.through_fields,
            )
            if signature in seen_intermediary_signatures:
                errors.append(
                    checks.Error(
                        "The model has two identical many-to-many relations "
                        "through the intermediate model '%s'."
                        % f.remote_field.through._meta.label,
                        obj=cls,
                        id="models.E003",
                    )
                )
            else:
                seen_intermediary_signatures.append(signature)
        return errors

    @classmethod
    def _check_id_field(cls):
        
        fields = [
            f for f in cls._meta.local_fields if f.name == "id" and f != cls._meta.pk
        ]
        
        if fields and not fields[0].primary_key and cls._meta.pk.name == "id":
            return [
                checks.Error(
                    "'id' can only be used as a field name if the field also "
                    "sets 'primary_key=True'.",
                    obj=cls,
                    id="models.E004",
                )
            ]
        else:
            return []

    @classmethod
    def _check_field_name_clashes(cls):
        
        errors = []
        used_fields = {}  

        
        for parent in cls._meta.get_parent_list():
            for f in parent._meta.local_fields:
                clash = used_fields.get(f.name) or used_fields.get(f.attname) or None
                if clash:
                    errors.append(
                        checks.Error(
                            "The field '%s' from parent model "
                            "'%s' clashes with the field '%s' "
                            "from parent model '%s'."
                            % (clash.name, clash.model._meta, f.name, f.model._meta),
                            obj=cls,
                            id="models.E005",
                        )
                    )
                used_fields[f.name] = f
                used_fields[f.attname] = f

        
        
        
        for parent in cls._meta.get_parent_list():
            for f in parent._meta.get_fields():
                if f not in used_fields:
                    used_fields[f.name] = f

        
        for parent_link in cls._meta.parents.values():
            if not parent_link:
                continue
            clash = used_fields.get(parent_link.name) or None
            if clash:
                errors.append(
                    checks.Error(
                        f"The field '{parent_link.name}' clashes with the field "
                        f"'{clash.name}' from model '{clash.model._meta}'.",
                        obj=cls,
                        id="models.E006",
                    )
                )

        for f in cls._meta.local_fields:
            clash = used_fields.get(f.name) or used_fields.get(f.attname) or None
            
            
            
            
            id_conflict = (
                f.name == "id" and clash and clash.name == "id" and clash.model == cls
            )
            if clash and not id_conflict:
                errors.append(
                    checks.Error(
                        "The field '%s' clashes with the field '%s' "
                        "from model '%s'." % (f.name, clash.name, clash.model._meta),
                        obj=f,
                        id="models.E006",
                    )
                )
            used_fields[f.name] = f
            used_fields[f.attname] = f

        return errors

    @classmethod
    def _check_column_name_clashes(cls):
        
        used_column_names = []
        errors = []

        for f in cls._meta.local_fields:
            _, column_name = f.get_attname_column()

            
            if column_name and column_name in used_column_names:
                errors.append(
                    checks.Error(
                        "Field '%s' has column name '%s' that is used by "
                        "another field." % (f.name, column_name),
                        hint="Specify a 'db_column' for the field.",
                        obj=cls,
                        id="models.E007",
                    )
                )
            else:
                used_column_names.append(column_name)

        return errors

    @classmethod
    def _check_model_name_db_lookup_clashes(cls):
        errors = []
        model_name = cls.__name__
        if model_name.startswith("_") or model_name.endswith("_"):
            errors.append(
                checks.Error(
                    "The model name '%s' cannot start or end with an underscore "
                    "as it collides with the query lookup syntax." % model_name,
                    obj=cls,
                    id="models.E023",
                )
            )
        elif LOOKUP_SEP in model_name:
            errors.append(
                checks.Error(
                    "The model name '%s' cannot contain double underscores as "
                    "it collides with the query lookup syntax." % model_name,
                    obj=cls,
                    id="models.E024",
                )
            )
        return errors

    @classmethod
    def _check_property_name_related_field_accessor_clashes(cls):
        errors = []
        property_names = cls._meta._property_names
        related_field_accessors = (
            f.get_attname()
            for f in cls._meta._get_fields(reverse=False)
            if f.is_relation and f.related_model is not None
        )
        for accessor in related_field_accessors:
            if accessor in property_names:
                errors.append(
                    checks.Error(
                        "The property '%s' clashes with a related field "
                        "accessor." % accessor,
                        obj=cls,
                        id="models.E025",
                    )
                )
        return errors

    @classmethod
    def _check_single_primary_key(cls):
        errors = []
        if sum(1 for f in cls._meta.local_fields if f.primary_key) > 1:
            errors.append(
                checks.Error(
                    "The model cannot have more than one field with "
                    "'primary_key=True'.",
                    obj=cls,
                    id="models.E026",
                )
            )
        return errors

    @classmethod
    def _check_unique_together(cls):
        
        if not isinstance(cls._meta.unique_together, (tuple, list)):
            return [
                checks.Error(
                    "'unique_together' must be a list or tuple.",
                    obj=cls,
                    id="models.E010",
                )
            ]

        elif any(
            not isinstance(fields, (tuple, list))
            for fields in cls._meta.unique_together
        ):
            return [
                checks.Error(
                    "All 'unique_together' elements must be lists or tuples.",
                    obj=cls,
                    id="models.E011",
                )
            ]

        else:
            errors = []
            for fields in cls._meta.unique_together:
                errors.extend(cls._check_local_fields(fields, "unique_together"))
            return errors

    @classmethod
    def _check_indexes(cls, databases):
        
        errors = []
        references = set()
        for index in cls._meta.indexes:
            
            
            if index.name[0] == "_" or index.name[0].isdigit():
                errors.append(
                    checks.Error(
                        "The index name '%s' cannot start with an underscore "
                        "or a number." % index.name,
                        obj=cls,
                        id="models.E033",
                    ),
                )
            if len(index.name) > index.max_name_length:
                errors.append(
                    checks.Error(
                        "The index name '%s' cannot be longer than %d "
                        "characters." % (index.name, index.max_name_length),
                        obj=cls,
                        id="models.E034",
                    ),
                )
            if index.contains_expressions:
                for expression in index.expressions:
                    references.update(
                        ref[0] for ref in cls._get_expr_references(expression)
                    )
        for db in databases:
            if not router.allow_migrate_model(db, cls):
                continue
            connection = connections[db]
            if not (
                connection.features.supports_partial_indexes
                or "supports_partial_indexes" in cls._meta.required_db_features
            ) and any(index.condition is not None for index in cls._meta.indexes):
                errors.append(
                    checks.Warning(
                        "%s does not support indexes with conditions."
                        % connection.display_name,
                        hint=(
                            "Conditions will be ignored. Silence this warning "
                            "if you don't care about it."
                        ),
                        obj=cls,
                        id="models.W037",
                    )
                )
            if not (
                connection.features.supports_covering_indexes
                or "supports_covering_indexes" in cls._meta.required_db_features
            ) and any(index.include for index in cls._meta.indexes):
                errors.append(
                    checks.Warning(
                        "%s does not support indexes with non-key columns."
                        % connection.display_name,
                        hint=(
                            "Non-key columns will be ignored. Silence this "
                            "warning if you don't care about it."
                        ),
                        obj=cls,
                        id="models.W040",
                    )
                )
            if not (
                connection.features.supports_expression_indexes
                or "supports_expression_indexes" in cls._meta.required_db_features
            ) and any(index.contains_expressions for index in cls._meta.indexes):
                errors.append(
                    checks.Warning(
                        "%s does not support indexes on expressions."
                        % connection.display_name,
                        hint=(
                            "An index won't be created. Silence this warning "
                            "if you don't care about it."
                        ),
                        obj=cls,
                        id="models.W043",
                    )
                )
        fields = [
            field for index in cls._meta.indexes for field, _ in index.fields_orders
        ]
        fields += [include for index in cls._meta.indexes for include in index.include]
        fields += references
        errors.extend(cls._check_local_fields(fields, "indexes"))
        return errors

    @classmethod
    def _check_local_fields(cls, fields, option):
        from django.db import models

        
        
        forward_fields_map = {}
        for field in cls._meta._get_fields(reverse=False):
            forward_fields_map[field.name] = field
            if hasattr(field, "attname"):
                forward_fields_map[field.attname] = field

        errors = []
        for field_name in fields:
            try:
                field = forward_fields_map[field_name]
            except KeyError:
                errors.append(
                    checks.Error(
                        "'%s' refers to the nonexistent field '%s'."
                        % (
                            option,
                            field_name,
                        ),
                        obj=cls,
                        id="models.E012",
                    )
                )
            else:
                if isinstance(field.remote_field, models.ManyToManyRel):
                    errors.append(
                        checks.Error(
                            "'%s' refers to a ManyToManyField '%s', but "
                            "ManyToManyFields are not permitted in '%s'."
                            % (
                                option,
                                field_name,
                                option,
                            ),
                            obj=cls,
                            id="models.E013",
                        )
                    )
                elif field not in cls._meta.local_fields:
                    errors.append(
                        checks.Error(
                            "'%s' refers to field '%s' which is not local to model "
                            "'%s'." % (option, field_name, cls._meta.object_name),
                            hint="This issue may be caused by multi-table inheritance.",
                            obj=cls,
                            id="models.E016",
                        )
                    )
        return errors

    @classmethod
    def _check_ordering(cls):
        
        if cls._meta._ordering_clash:
            return [
                checks.Error(
                    "'ordering' and 'order_with_respect_to' cannot be used together.",
                    obj=cls,
                    id="models.E021",
                ),
            ]

        if cls._meta.order_with_respect_to or not cls._meta.ordering:
            return []

        if not isinstance(cls._meta.ordering, (list, tuple)):
            return [
                checks.Error(
                    "'ordering' must be a tuple or list (even if you want to order by "
                    "only one field).",
                    obj=cls,
                    id="models.E014",
                )
            ]

        errors = []
        fields = cls._meta.ordering

        
        fields = (f for f in fields if isinstance(f, str) and f != "?")

        
        fields = (f.removeprefix("-") for f in fields)

        
        _fields = []
        related_fields = []
        for f in fields:
            if LOOKUP_SEP in f:
                related_fields.append(f)
            else:
                _fields.append(f)
        fields = _fields

        
        for field in related_fields:
            _cls = cls
            fld = None
            for part in field.split(LOOKUP_SEP):
                try:
                    
                    if part == "pk":
                        fld = _cls._meta.pk
                    else:
                        fld = _cls._meta.get_field(part)
                    if fld.is_relation:
                        _cls = fld.path_infos[-1].to_opts.model
                    else:
                        _cls = None
                except (FieldDoesNotExist, AttributeError):
                    if fld is None or (
                        fld.get_transform(part) is None and fld.get_lookup(part) is None
                    ):
                        errors.append(
                            checks.Error(
                                "'ordering' refers to the nonexistent field, "
                                "related field, or lookup '%s'." % field,
                                obj=cls,
                                id="models.E015",
                            )
                        )

        
        
        fields = {f for f in fields if f != "pk"}

        
        invalid_fields = []

        
        
        opts = cls._meta
        valid_fields = set(
            chain.from_iterable(
                (f.name, f.attname)
                if not (f.auto_created and not f.concrete)
                else (f.field.related_query_name(),)
                for f in chain(opts.fields, opts.related_objects)
            )
        )

        invalid_fields.extend(fields - valid_fields)

        for invalid_field in invalid_fields:
            errors.append(
                checks.Error(
                    "'ordering' refers to the nonexistent field, related "
                    "field, or lookup '%s'." % invalid_field,
                    obj=cls,
                    id="models.E015",
                )
            )
        return errors

    @classmethod
    def _check_long_column_names(cls, databases):
        
        if not databases:
            return []
        errors = []
        allowed_len = None
        db_alias = None

        
        for db in databases:
            
            if not router.allow_migrate_model(db, cls):
                continue
            connection = connections[db]
            max_name_length = connection.ops.max_name_length()
            if max_name_length is None or connection.features.truncates_names:
                continue
            else:
                if allowed_len is None:
                    allowed_len = max_name_length
                    db_alias = db
                elif max_name_length < allowed_len:
                    allowed_len = max_name_length
                    db_alias = db

        if allowed_len is None:
            return errors

        for f in cls._meta.local_fields:
            _, column_name = f.get_attname_column()

            
            
            if (
                f.db_column is None
                and column_name is not None
                and len(column_name) > allowed_len
            ):
                errors.append(
                    checks.Error(
                        'Autogenerated column name too long for field "%s". '
                        'Maximum length is "%s" for database "%s".'
                        % (column_name, allowed_len, db_alias),
                        hint="Set the column name manually using 'db_column'.",
                        obj=cls,
                        id="models.E018",
                    )
                )

        for f in cls._meta.local_many_to_many:
            
            if isinstance(f.remote_field.through, str):
                continue

            
            
            for m2m in f.remote_field.through._meta.local_fields:
                _, rel_name = m2m.get_attname_column()
                if (
                    m2m.db_column is None
                    and rel_name is not None
                    and len(rel_name) > allowed_len
                ):
                    errors.append(
                        checks.Error(
                            "Autogenerated column name too long for M2M field "
                            '"%s". Maximum length is "%s" for database "%s".'
                            % (rel_name, allowed_len, db_alias),
                            hint=(
                                "Use 'through' to create a separate model for "
                                "M2M and then set column_name using 'db_column'."
                            ),
                            obj=cls,
                            id="models.E019",
                        )
                    )

        return errors

    @classmethod
    def _get_expr_references(cls, expr):
        if isinstance(expr, Q):
            for child in expr.children:
                if isinstance(child, tuple):
                    lookup, value = child
                    yield tuple(lookup.split(LOOKUP_SEP))
                    yield from cls._get_expr_references(value)
                else:
                    yield from cls._get_expr_references(child)
        elif isinstance(expr, F):
            yield tuple(expr.name.split(LOOKUP_SEP))
        elif hasattr(expr, "get_source_expressions"):
            for src_expr in expr.get_source_expressions():
                yield from cls._get_expr_references(src_expr)

    @classmethod
    def _check_constraints(cls, databases):
        errors = []
        for db in databases:
            if not router.allow_migrate_model(db, cls):
                continue
            connection = connections[db]
            if not (
                connection.features.supports_table_check_constraints
                or "supports_table_check_constraints" in cls._meta.required_db_features
            ) and any(
                isinstance(constraint, CheckConstraint)
                for constraint in cls._meta.constraints
            ):
                errors.append(
                    checks.Warning(
                        "%s does not support check constraints."
                        % connection.display_name,
                        hint=(
                            "A constraint won't be created. Silence this "
                            "warning if you don't care about it."
                        ),
                        obj=cls,
                        id="models.W027",
                    )
                )
            if not (
                connection.features.supports_partial_indexes
                or "supports_partial_indexes" in cls._meta.required_db_features
            ) and any(
                isinstance(constraint, UniqueConstraint)
                and constraint.condition is not None
                for constraint in cls._meta.constraints
            ):
                errors.append(
                    checks.Warning(
                        "%s does not support unique constraints with "
                        "conditions." % connection.display_name,
                        hint=(
                            "A constraint won't be created. Silence this "
                            "warning if you don't care about it."
                        ),
                        obj=cls,
                        id="models.W036",
                    )
                )
            if not (
                connection.features.supports_deferrable_unique_constraints
                or "supports_deferrable_unique_constraints"
                in cls._meta.required_db_features
            ) and any(
                isinstance(constraint, UniqueConstraint)
                and constraint.deferrable is not None
                for constraint in cls._meta.constraints
            ):
                errors.append(
                    checks.Warning(
                        "%s does not support deferrable unique constraints."
                        % connection.display_name,
                        hint=(
                            "A constraint won't be created. Silence this "
                            "warning if you don't care about it."
                        ),
                        obj=cls,
                        id="models.W038",
                    )
                )
            if not (
                connection.features.supports_covering_indexes
                or "supports_covering_indexes" in cls._meta.required_db_features
            ) and any(
                isinstance(constraint, UniqueConstraint) and constraint.include
                for constraint in cls._meta.constraints
            ):
                errors.append(
                    checks.Warning(
                        "%s does not support unique constraints with non-key "
                        "columns." % connection.display_name,
                        hint=(
                            "A constraint won't be created. Silence this "
                            "warning if you don't care about it."
                        ),
                        obj=cls,
                        id="models.W039",
                    )
                )
            if not (
                connection.features.supports_expression_indexes
                or "supports_expression_indexes" in cls._meta.required_db_features
            ) and any(
                isinstance(constraint, UniqueConstraint)
                and constraint.contains_expressions
                for constraint in cls._meta.constraints
            ):
                errors.append(
                    checks.Warning(
                        "%s does not support unique constraints on "
                        "expressions." % connection.display_name,
                        hint=(
                            "A constraint won't be created. Silence this "
                            "warning if you don't care about it."
                        ),
                        obj=cls,
                        id="models.W044",
                    )
                )
            if not (
                connection.features.supports_nulls_distinct_unique_constraints
                or (
                    "supports_nulls_distinct_unique_constraints"
                    in cls._meta.required_db_features
                )
            ) and any(
                isinstance(constraint, UniqueConstraint)
                and constraint.nulls_distinct is not None
                for constraint in cls._meta.constraints
            ):
                errors.append(
                    checks.Warning(
                        "%s does not support unique constraints with "
                        "nulls distinct." % connection.display_name,
                        hint=(
                            "A constraint won't be created. Silence this "
                            "warning if you don't care about it."
                        ),
                        obj=cls,
                        id="models.W047",
                    )
                )
            fields = set(
                chain.from_iterable(
                    (*constraint.fields, *constraint.include)
                    for constraint in cls._meta.constraints
                    if isinstance(constraint, UniqueConstraint)
                )
            )
            references = set()
            for constraint in cls._meta.constraints:
                if isinstance(constraint, UniqueConstraint):
                    if (
                        connection.features.supports_partial_indexes
                        or "supports_partial_indexes"
                        not in cls._meta.required_db_features
                    ) and isinstance(constraint.condition, Q):
                        references.update(
                            cls._get_expr_references(constraint.condition)
                        )
                    if (
                        connection.features.supports_expression_indexes
                        or "supports_expression_indexes"
                        not in cls._meta.required_db_features
                    ) and constraint.contains_expressions:
                        for expression in constraint.expressions:
                            references.update(cls._get_expr_references(expression))
                elif isinstance(constraint, CheckConstraint):
                    if (
                        connection.features.supports_table_check_constraints
                        or "supports_table_check_constraints"
                        not in cls._meta.required_db_features
                    ):
                        if isinstance(constraint.check, Q):
                            references.update(
                                cls._get_expr_references(constraint.check)
                            )
                        if any(
                            isinstance(expr, RawSQL)
                            for expr in constraint.check.flatten()
                        ):
                            errors.append(
                                checks.Warning(
                                    f"Check constraint {constraint.name!r} contains "
                                    f"RawSQL() expression and won't be validated "
                                    f"during the model full_clean().",
                                    hint=(
                                        "Silence this warning if you don't care about "
                                        "it."
                                    ),
                                    obj=cls,
                                    id="models.W045",
                                ),
                            )
            for field_name, *lookups in references:
                
                if field_name != "pk":
                    fields.add(field_name)
                if not lookups:
                    
                    continue
                try:
                    if field_name == "pk":
                        field = cls._meta.pk
                    else:
                        field = cls._meta.get_field(field_name)
                    if not field.is_relation or field.many_to_many or field.one_to_many:
                        continue
                except FieldDoesNotExist:
                    continue
                
                first_lookup = lookups[0]
                if (
                    hasattr(field, "get_transform")
                    and hasattr(field, "get_lookup")
                    and field.get_transform(first_lookup) is None
                    and field.get_lookup(first_lookup) is None
                ):
                    errors.append(
                        checks.Error(
                            "'constraints' refers to the joined field '%s'."
                            % LOOKUP_SEP.join([field_name] + lookups),
                            obj=cls,
                            id="models.E041",
                        )
                    )
            errors.extend(cls._check_local_fields(fields, "constraints"))
        return errors









def method_set_order(self, ordered_obj, id_list, using=None):
    order_wrt = ordered_obj._meta.order_with_respect_to
    filter_args = order_wrt.get_forward_related_filter(self)
    ordered_obj.objects.db_manager(using).filter(**filter_args).bulk_update(
        [ordered_obj(pk=pk, _order=order) for order, pk in enumerate(id_list)],
        ["_order"],
    )


def method_get_order(self, ordered_obj):
    order_wrt = ordered_obj._meta.order_with_respect_to
    filter_args = order_wrt.get_forward_related_filter(self)
    pk_name = ordered_obj._meta.pk.name
    return ordered_obj.objects.filter(**filter_args).values_list(pk_name, flat=True)


def make_foreign_order_accessors(model, related_model):
    setattr(
        related_model,
        "get_%s_order" % model.__name__.lower(),
        partialmethod(method_get_order, model),
    )
    setattr(
        related_model,
        "set_%s_order" % model.__name__.lower(),
        partialmethod(method_set_order, model),
    )







def model_unpickle(model_id):
    
    if isinstance(model_id, tuple):
        model = apps.get_model(*model_id)
    else:
        
        model = model_id
    return model.__new__(model)


model_unpickle.__safe_for_unpickle__ = True