@@ -110,8 +110,9 @@ class Field[T](RegisterLookupMixin):
110110 cast_db_type_sql : str | None = None
111111
112112 # Instance attributes set during field lifecycle
113- # Set by __init__
114- name : str | None
113+ # Set by __init__; becomes the real field name once contributed to a
114+ # model class (set_attributes_from_name, called by contribute_to_class)
115+ name : str
115116 # Set by set_attributes_from_name (called by contribute_to_class)
116117 column : str
117118 concrete : bool
@@ -134,7 +135,7 @@ class Field[T](RegisterLookupMixin):
134135 non_migration_attrs : tuple [str , ...] = ()
135136
136137 def __init__ (self ) -> None :
137- self .name = None # Set by set_attributes_from_name
138+ self .name = "" # Set by set_attributes_from_name
138139 self .primary_key = False
139140 self .auto_created = False
140141
@@ -151,8 +152,8 @@ def __str__(self) -> str:
151152 def __repr__ (self ) -> str :
152153 """Display the module, class, and name of the field."""
153154 path = f"{ self .__class__ .__module__ } .{ self .__class__ .__qualname__ } "
154- name = getattr (self , "name" , None )
155- if name is not None :
155+ name = getattr (self , "name" , "" )
156+ if name :
156157 return f"<{ path } : { name } >"
157158 return f"<{ path } >"
158159
@@ -164,7 +165,6 @@ def _check_field_name(self) -> list[PreflightResult]:
164165 Check if field name is valid, i.e. 1) does not end with an
165166 underscore, 2) does not contain "__" and 3) is not "id".
166167 """
167- assert self .name is not None , "Field name must be set before checking"
168168 if self .name .endswith ("_" ):
169169 return [
170170 PreflightResult (
@@ -215,7 +215,7 @@ def select_format(
215215 """
216216 return sql , params
217217
218- def deconstruct (self ) -> tuple [str | None , str , list [Any ], dict [str , Any ]]:
218+ def deconstruct (self ) -> tuple [str , str , list [Any ], dict [str , Any ]]:
219219 """
220220 Return enough information to recreate the field as a 4-tuple:
221221
@@ -259,7 +259,6 @@ def deconstruct(self) -> tuple[str | None, str, list[Any], dict[str, Any]]:
259259 cls_name = self .__class__ .__qualname__
260260 if getattr (_postgres_root , cls_name , None ) is self .__class__ :
261261 path = f"plain.postgres.{ cls_name } "
262- # Note: self.name can be None during migration state rendering when fields are cloned
263262 return (self .name , path , [], keywords )
264263
265264 def clone (self ) -> Self :
@@ -305,7 +304,6 @@ def __reduce__(
305304 # values - so, this is very close to normal pickle.
306305 state = self .__dict__ .copy ()
307306 return _empty , (self .__class__ ,), state
308- assert self .name is not None
309307 options = model .model_options
310308 return _load_field , (
311309 options .package_label ,
@@ -394,7 +392,6 @@ def contribute_to_class(self, cls: type[Model], name: str) -> None:
394392 # Field is its own descriptor; make sure it is set on the class so
395393 # attribute access hits __get__/__set__.
396394 if self .column :
397- assert self .name is not None
398395 setattr (cls , self .name , self )
399396
400397 # Descriptor protocol implementation
@@ -422,7 +419,6 @@ def __get__(self, instance: Model | None, owner: type[Model]) -> Self | T:
422419 return self
423420
424421 # Instance access - get value from instance dict
425- assert self .name is not None
426422 data = instance .__dict__
427423 field_name = self .name
428424
@@ -472,7 +468,6 @@ def __set__(self, instance: Model, value: T) -> None:
472468 stored = self .to_python (value )
473469
474470 # Store in instance dict
475- assert self .name is not None
476471 instance .__dict__ [self .name ] = stored
477472
478473 def __delete__ (self , instance : Model ) -> None :
@@ -481,7 +476,6 @@ def __delete__(self, instance: Model) -> None:
481476
482477 Removes the value from instance.__dict__.
483478 """
484- assert self .name is not None
485479 try :
486480 del instance .__dict__ [self .name ]
487481 except KeyError :
@@ -491,7 +485,6 @@ def __delete__(self, instance: Model) -> None:
491485
492486 def pre_save (self , model_instance : Model , add : bool ) -> T | None :
493487 """Return field's value just before saving."""
494- assert self .name is not None
495488 return getattr (model_instance , self .name )
496489
497490 def get_prep_value (self , value : Any ) -> Any :
@@ -544,12 +537,10 @@ def has_db_default(self) -> bool:
544537 return self .get_db_default_expression () is not None
545538
546539 def save_form_data (self , instance : Model , data : Any ) -> None :
547- assert self .name is not None
548540 setattr (instance , self .name , data )
549541
550542 def value_from_object (self , obj : Model ) -> T | None :
551543 """Return the value of this field in the given model instance."""
552- assert self .name is not None
553544 return getattr (obj , self .name )
554545
555546
@@ -653,7 +644,7 @@ def get_default(self) -> Any:
653644 return None
654645 return self ._default_empty_value
655646
656- def deconstruct (self ) -> tuple [str | None , str , list [Any ], dict [str , Any ]]:
647+ def deconstruct (self ) -> tuple [str , str , list [Any ], dict [str , Any ]]:
657648 name , path , args , kwargs = super ().deconstruct ()
658649 if self .required is not True :
659650 kwargs ["required" ] = self .required
@@ -750,7 +741,7 @@ def get_default(self) -> Any:
750741 # shared state across instances.
751742 return copy .deepcopy (self .default )
752743
753- def deconstruct (self ) -> tuple [str | None , str , list [Any ], dict [str , Any ]]:
744+ def deconstruct (self ) -> tuple [str , str , list [Any ], dict [str , Any ]]:
754745 name , path , args , kwargs = super ().deconstruct ()
755746 if self .default is not NOT_PROVIDED :
756747 kwargs ["default" ] = self .default
@@ -891,7 +882,7 @@ def validate(self, value: Any, model_instance: Model) -> None:
891882 )
892883 super ().validate (value , model_instance )
893884
894- def deconstruct (self ) -> tuple [str | None , str , list [Any ], dict [str , Any ]]:
885+ def deconstruct (self ) -> tuple [str , str , list [Any ], dict [str , Any ]]:
895886 name , path , args , kwargs = super ().deconstruct ()
896887 if self .choices is not None :
897888 choices = self .choices
0 commit comments