def CountIf(field, expression, **extra): return Count( Case( When(expression, then=F(field), **extra), default=None, output_field=Field(), ))
def resolve_ref(name: str, *_: Any, **__: Any) -> 'Col': from django.db.models.expressions import Col from django.db.models.fields import Field # We need to do some faking of the ref resolution. # This essentially enables us to have a bit more complete # workings of F(). # An interesting point to raise here is, we need to pass a Field in. # However, it doesn't need to be the "correct" field. At this point, # all conversion has been done, so now we just need to get a valid # target in. return Col(name, Field())
def field(self): return Field(name=sentinel.FIELD_NAME)
def __init__(self, token): """ Constructor for `QueryField`. This constructor tries to define a valid query field with all corresponding values for further processing in the context of DB querying. Example: QueryField('comment') -> Machine.comment QueryField('comment_length') -> Machine.comment (for querying the char length) QueryField('ipv4') -> Machine.ipv4 (dynamic field) QueryField('installations__comment') -> Machine.installations.comment (related field) """ self._field = None self._related_name = None self._verbose_name = None self._dynamic = False self._pre_function = None self._post_function = None if self.LENGTH_SUFFIX in token: token = token.replace(self.LENGTH_SUFFIX, '') self._annotation = self.LENGTH_SUFFIX else: self._annotation = None try: self._field = self.MAPPING[token]['field'] self._verbose_name = self.MAPPING[token].get('verbose_name') if not self._verbose_name: self._verbose_name = Machine._meta.get_field( self._field.name).verbose_name self._related_name = self.MAPPING[token].get('related_name') self._pre_function = self.MAPPING[token].get('pre') self._post_function = self.MAPPING[token].get('post') except KeyError: pass if not self._field and (token in self.DYNAMIC_FIELDS): self._field = Field(name=token) self._verbose_name = self.DYNAMIC_FIELDS[ self._field.name]['verbose_name'] self._dynamic_field_function = self.DYNAMIC_FIELDS[ self._field.name]['function'] self._dynamic = True if not self._field: try: self._field = Machine._meta.get_field(token) self._verbose_name = self._field.verbose_name except FieldDoesNotExist: pass if not self._field: related_name = '__'.join(token.split('__')[:-1]) field_name = token.split('__')[-1] if related_name: for token, values in self.MAPPING.items(): if related_name == values.get('related_name'): if field_name == values['field'].name: self._field = self.MAPPING[token]['field'] self._related_name = related_name self._verbose_name = self.MAPPING[token][ 'verbose_name'] self._pre_function = self.MAPPING[token].get('pre') self._post_function = self.MAPPING[token].get( 'post') if not self._field: raise ValueError("Unknown field '{}'!".format(token))
def transform_to_field(key): field = Field(name=key) return field