fix server_default not setting value in defaults, pop server_default fields if set to None, add tests, update docs

This commit is contained in:
collerek
2020-10-28 15:34:40 +01:00
parent 858fbce67f
commit 29d04887b1
8 changed files with 150 additions and 17 deletions

View File

@ -28,7 +28,7 @@ class UndefinedType: # pragma no cover
Undefined = UndefinedType()
__version__ = "0.3.9"
__version__ = "0.3.11"
__all__ = [
"Integer",
"BigInteger",

View File

@ -33,10 +33,10 @@ class BaseField:
server_default: Any
@classmethod
def default_value(cls) -> Optional[FieldInfo]:
def default_value(cls, use_server: bool = False) -> Optional[FieldInfo]:
if cls.is_auto_primary_key():
return Field(default=None)
if cls.has_default():
if cls.has_default(use_server=use_server):
default = cls.default if cls.default is not None else cls.server_default
if callable(default):
return Field(default_factory=default)
@ -44,16 +44,22 @@ class BaseField:
return None
@classmethod
def get_default(cls) -> Any:
def get_default(cls, use_server: bool = False) -> Any: # noqa CCR001
if cls.has_default():
default = cls.default if cls.default is not None else cls.server_default
default = (
cls.default
if cls.default is not None
else (cls.server_default if use_server else None)
)
if callable(default):
default = default()
return default
@classmethod
def has_default(cls) -> bool:
return cls.default is not None or cls.server_default is not None
def has_default(cls, use_server: bool = True) -> bool:
return cls.default is not None or (
cls.server_default is not None and use_server
)
@classmethod
def is_auto_primary_key(cls) -> bool:

View File

@ -129,7 +129,7 @@ class Model(NewBaseModel):
if not self.pk and self.Meta.model_fields[self.Meta.pkname].autoincrement:
self_fields.pop(self.Meta.pkname, None)
self_fields = self.objects._populate_default_values(self_fields)
self_fields = self.populate_default_values(self_fields)
expr = self.Meta.table.insert()
expr = expr.values(**self_fields)
item_id = await self.Meta.database.execute(expr)

View File

@ -49,6 +49,16 @@ class ModelTableProxy:
model_dict.pop(field, None)
return model_dict
@classmethod
def populate_default_values(cls, new_kwargs: Dict) -> Dict:
for field_name, field in cls.Meta.model_fields.items():
if field_name not in new_kwargs and field.has_default(use_server=False):
new_kwargs[field_name] = field.get_default()
# clear fields with server_default set as None
if field.server_default is not None and not new_kwargs.get(field_name):
new_kwargs.pop(field_name, None)
return new_kwargs
@classmethod
def get_column_alias(cls, field_name: str) -> str:
field = cls.Meta.model_fields.get(field_name)

View File

@ -73,16 +73,10 @@ class QuerySet:
def _prepare_model_to_save(self, new_kwargs: dict) -> dict:
new_kwargs = self._remove_pk_from_kwargs(new_kwargs)
new_kwargs = self.model.substitute_models_with_pks(new_kwargs)
new_kwargs = self._populate_default_values(new_kwargs)
new_kwargs = self.model.populate_default_values(new_kwargs)
new_kwargs = self.model.translate_columns_to_aliases(new_kwargs)
return new_kwargs
def _populate_default_values(self, new_kwargs: dict) -> dict:
for field_name, field in self.model_meta.model_fields.items():
if field_name not in new_kwargs and field.has_default():
new_kwargs[field_name] = field.get_default()
return new_kwargs
def _remove_pk_from_kwargs(self, new_kwargs: dict) -> dict:
pkname = self.model_meta.pkname
pk = self.model_meta.model_fields[pkname]
@ -300,6 +294,9 @@ class QuerySet:
if pk and isinstance(pk, self.model.pk_type()):
setattr(instance, self.model_meta.pkname, pk)
# refresh server side defaults
instance = await instance.load()
return instance
async def bulk_create(self, objects: List["Model"]) -> None: