fix merging non relation list fields

This commit is contained in:
collerek
2021-03-31 17:07:42 +02:00
parent 4dc11b0de4
commit 749975d665
6 changed files with 102 additions and 29 deletions

View File

@ -60,20 +60,23 @@ class MergeModelMixin:
:return: current Model instance with data merged from previous one.
:rtype: Model
"""
for field in one.Meta.model_fields.keys():
current_field = getattr(one, field)
if isinstance(current_field, list) and not isinstance(
current_field, ormar.Model
):
setattr(other, field, current_field + getattr(other, field))
elif (
isinstance(current_field, ormar.Model)
and current_field.pk == getattr(other, field).pk
):
setattr(
other,
field,
cls.merge_two_instances(current_field, getattr(other, field)),
)
for field_name, field in one.Meta.model_fields.items():
current_field = getattr(one, field_name)
if field.is_relation:
if isinstance(current_field, list):
setattr(
other, field_name, current_field + getattr(other, field_name)
)
elif (
isinstance(current_field, ormar.Model)
and current_field.pk == getattr(other, field_name).pk
):
setattr(
other,
field_name,
cls.merge_two_instances(
current_field, getattr(other, field_name)
),
)
other.set_save_status(True)
return other

View File

@ -150,15 +150,16 @@ class Model(ModelRow):
for related in self.extract_related_names():
if relation_map and related in relation_map:
value = getattr(self, related)
update_count = await self._update_and_follow(
value=value,
follow=follow,
save_all=save_all,
relation_map=self._skip_ellipsis( # type: ignore
relation_map, related, default_return={}
),
update_count=update_count,
)
if value:
update_count = await self._update_and_follow(
value=value,
follow=follow,
save_all=save_all,
relation_map=self._skip_ellipsis( # type: ignore
relation_map, related, default_return={}
),
update_count=update_count,
)
return update_count
@staticmethod

View File

@ -650,7 +650,7 @@ class QuerySet(Generic[T]):
:return: number of updated rows
:rtype: int
"""
if not each and not self.filter_clauses:
if not each and not (self.filter_clauses or self.exclude_clauses):
raise QueryDefinitionError(
"You cannot update without filtering the queryset first. "
"If you want to update all rows use update(each=True, **kwargs)"
@ -666,6 +666,9 @@ class QuerySet(Generic[T]):
expr = FilterQuery(filter_clauses=self.filter_clauses).apply(
self.table.update().values(**updates)
)
expr = FilterQuery(filter_clauses=self.exclude_clauses, exclude=True).apply(
expr
)
return await self.database.execute(expr)
async def delete(self, each: bool = False, **kwargs: Any) -> int:
@ -684,7 +687,7 @@ class QuerySet(Generic[T]):
"""
if kwargs:
return await self.filter(**kwargs).delete()
if not each and not self.filter_clauses:
if not each and not (self.filter_clauses or self.exclude_clauses):
raise QueryDefinitionError(
"You cannot delete without filtering the queryset first. "
"If you want to delete all rows use delete(each=True)"
@ -692,6 +695,9 @@ class QuerySet(Generic[T]):
expr = FilterQuery(filter_clauses=self.filter_clauses).apply(
self.table.delete()
)
expr = FilterQuery(filter_clauses=self.exclude_clauses, exclude=True).apply(
expr
)
return await self.database.execute(expr)
def paginate(self, page: int, page_size: int = 20) -> "QuerySet[T]":

View File

@ -389,7 +389,11 @@ class QuerysetProxy(Generic[T]):
:rtype: int
"""
# queryset proxy always have one filter for pk of parent model
if not each and len(self.queryset.filter_clauses) == 1:
if (
not each
and (len(self.queryset.filter_clauses) + len(self.queryset.exclude_clauses))
== 1
):
raise QueryDefinitionError(
"You cannot update without filtering the queryset first. "
"If you want to update all rows use update(each=True, **kwargs)"