| 9 | |
| 10 | |
| 11 | class GeneratedField(Field): |
| 12 | generated = True |
| 13 | db_returning = True |
| 14 | |
| 15 | _query = None |
| 16 | output_field = None |
| 17 | |
| 18 | def __init__(self, *, expression, output_field, db_persist, **kwargs): |
| 19 | if kwargs.setdefault("editable", False): |
| 20 | raise ValueError("GeneratedField cannot be editable.") |
| 21 | if not kwargs.setdefault("blank", True): |
| 22 | raise ValueError("GeneratedField must be blank.") |
| 23 | if kwargs.get("default", NOT_PROVIDED) is not NOT_PROVIDED: |
| 24 | raise ValueError("GeneratedField cannot have a default.") |
| 25 | if kwargs.get("db_default", NOT_PROVIDED) is not NOT_PROVIDED: |
| 26 | raise ValueError("GeneratedField cannot have a database default.") |
| 27 | if db_persist not in (True, False): |
| 28 | raise ValueError("GeneratedField.db_persist must be True or False.") |
| 29 | |
| 30 | self.expression = expression |
| 31 | self.output_field = output_field |
| 32 | self.db_persist = db_persist |
| 33 | self.has_null_arg = "null" in kwargs |
| 34 | super().__init__(**kwargs) |
| 35 | |
| 36 | @cached_property |
| 37 | def cached_col(self): |
| 38 | from django.db.models.expressions import Col |
| 39 | |
| 40 | return Col(self.model._meta.db_table, self, self.output_field) |
| 41 | |
| 42 | def get_col(self, alias, output_field=None): |
| 43 | if alias != self.model._meta.db_table and output_field in (None, self): |
| 44 | output_field = self.output_field |
| 45 | return super().get_col(alias, output_field) |
| 46 | |
| 47 | def contribute_to_class(self, *args, **kwargs): |
| 48 | super().contribute_to_class(*args, **kwargs) |
| 49 | |
| 50 | self._query = Query(model=self.model, alias_cols=False) |
| 51 | # Register lookups from the output_field class. |
| 52 | for lookup_name, lookup in self.output_field.get_class_lookups().items(): |
| 53 | self.register_lookup(lookup, lookup_name=lookup_name) |
| 54 | |
| 55 | def generated_sql(self, connection): |
| 56 | compiler = connection.ops.compiler("SQLCompiler")( |
| 57 | self._query, connection=connection, using=None |
| 58 | ) |
| 59 | resolved_expression = self.expression.resolve_expression( |
| 60 | self._query, allow_joins=False |
| 61 | ) |
| 62 | sql, params = compiler.compile(resolved_expression) |
| 63 | if ( |
| 64 | getattr(self.expression, "conditional", False) |
| 65 | and not connection.features.supports_boolean_expr_in_select_clause |
| 66 | ): |
| 67 | sql = f"CASE WHEN {sql} THEN 1 ELSE 0 END" |
| 68 | return sql, params |
no outgoing calls