Generates the SQL for updating a model depending on provided update_fields. Result is cached for performance.
(
self,
update_fields: Iterable[str] | None,
expressions: dict[str, Expression] | None,
)
| 375 | setattr(instance, model_field, field_object.to_python_value(raw_value)) |
| 376 | |
| 377 | def get_update_sql( |
| 378 | self, |
| 379 | update_fields: Iterable[str] | None, |
| 380 | expressions: dict[str, Expression] | None, |
| 381 | ) -> str: |
| 382 | """ |
| 383 | Generates the SQL for updating a model depending on provided update_fields. |
| 384 | Result is cached for performance. |
| 385 | """ |
| 386 | key = ",".join(update_fields) if update_fields else "" |
| 387 | if not expressions and key in self.update_cache: |
| 388 | return self.update_cache[key] |
| 389 | expressions = expressions or {} |
| 390 | table = self.model._meta.basetable |
| 391 | query = self.db.query_class.update(table) |
| 392 | parameter_idx = 0 |
| 393 | for field in update_fields or self.model._meta.fields_db_projection.keys(): |
| 394 | db_column = self.model._meta.fields_db_projection[field] |
| 395 | field_object = self.model._meta.fields_map[field] |
| 396 | if field_object.generated: |
| 397 | if update_fields: |
| 398 | raise OperationalError(f"Can't update generated field {field}") |
| 399 | continue |
| 400 | if not field_object.pk: |
| 401 | if field not in expressions.keys(): |
| 402 | query = query.set(db_column, self.parameter(parameter_idx)) |
| 403 | parameter_idx += 1 |
| 404 | else: |
| 405 | value = ( |
| 406 | expressions[field] |
| 407 | .resolve( |
| 408 | ResolveContext( |
| 409 | model=self.model, |
| 410 | table=table, |
| 411 | annotations={}, |
| 412 | custom_filters={}, |
| 413 | ) |
| 414 | ) |
| 415 | .term |
| 416 | ) |
| 417 | query = query.set(db_column, value) |
| 418 | |
| 419 | query = query.where(table[self.model._meta.db_pk_column] == self.parameter(parameter_idx)) |
| 420 | |
| 421 | sql = query.get_sql() |
| 422 | if not expressions: |
| 423 | self.update_cache[key] = sql |
| 424 | return sql |
| 425 | |
| 426 | async def execute_update( |
| 427 | self, instance: type[Model] | Model, update_fields: Iterable[str] | None |
no test coverage detected