def __init__(self, target: models.Field): default = self.NO_DEFAULT if target.has_default(): if isinstance(target.get_default(), Enum): default = target.get_default().value else: default = target.get_default() choices = None if target.choices: choices = [] for value, label in target.choices: choices.append(label) super().__init__(name=target.name, type=self.define_representation_type(target), description=target.help_text, default=default, is_required=self.check_is_required(target), choices=choices) if self.type is Attribute.TYPE.OBJECT: if isinstance(target, (models.OneToOneField, models.ForeignKey)): self.type_of = target.related_model else: raise NotImplementedError() if self.type is Attribute.TYPE.ARRAY: self.type_of = target.related_model if self.type is Attribute.TYPE.FILE: self.type = Attribute.TYPE.STRING self.target = target
def _handle_o2m_related_field(self, related_field: Field, alias_object: Model): try: reverse_o2m_accessor_name = related_field.get_accessor_name() except AttributeError: # get_accessor_name does not exist for <django.contrib.contenttypes.fields.GenericRelation> reverse_o2m_accessor_name = related_field.get_attname() try: o2m_accessor_name = related_field.field.name except AttributeError: o2m_accessor_name = related_field.name for obj in getattr(alias_object, reverse_o2m_accessor_name).all(): try: logger.debug(f'Attempting to set o2m field {o2m_accessor_name} on ' f'{obj._meta.model.__name__}[pk={obj.pk}] to ' f'{self.model_meta.model_name}[pk={self.primary_object.pk}] ...') setattr(obj, o2m_accessor_name, self.primary_object) obj.validate_unique() obj.save() logger.debug('success.') except ValidationError as e: logger.debug(f'failed. {e}') if related_field.field.null: logger.debug(f'Setting o2m field {o2m_accessor_name} on ' f'{obj._meta.model.__name__}[pk={obj.pk}] to `None`') setattr(obj, o2m_accessor_name, None) obj.save() else: logger.debug(f'Deleting {obj._meta.model.__name__}[pk={obj.pk}]') obj.delete() self.modified_related_objects.append(obj)
def column_sql(self, model: Model, field: Field, include_default=False) -> Tuple[str, list]: # Get the column's type and use that as the basis of the SQL db_params = field.db_parameters(connection=self.connection) sql = db_params['type'] params = [] # Check for fields that aren't actually columns (e.g. M2M) if sql is None: return None, None if field.null and not self.connection.features.implied_column_null: sql += ' NULL' # Check constraints if not field.null: check = '%s IS NOT NULL' % self.quote_name(field.column) self.deferred_column_sql['CHECK'].append( self._create_check_sql_for_field(model, field, check, qualifier='_nn')) db_params = field.db_parameters(connection=self.connection) if db_params['check']: self.deferred_column_sql['CHECK'].append( self._create_check_sql_for_field(model, field, db_params['check'])) # Primary/unique keys if field.primary_key: self.deferred_column_sql['PRIMARY_KEY'].append( self._create_primary_key_sql(model, field)) elif field.unique: self.deferred_column_sql['UNIQUE'].append( self._create_unique_sql(model, [field.column])) # FK if field.remote_field and field.db_constraint: self.deferred_column_sql['FOREIGN_KEY'].append( self._create_fk_sql(model, field, suffix='_fk_%(to_table)s_%(to_column)s')) # Autoincrement SQL (for backends with post table definition variant) if field.get_internal_type() in ('AutoField', 'BigAutoField'): autoinc_sql = self.connection.ops.autoinc_sql( model._meta.db_table, field.column) if autoinc_sql: self.deferred_column_sql['AUTOINCREMENT'].extend(autoinc_sql) # Comment columns for fields with help_text if field.help_text: self.deferred_column_sql['COMMENT'].append( self._create_comment_sql(model, field)) return sql, params
def __init__(self, *args, **kwargs): if kwargs.get("auto_now", False): self.auto_now = True kwargs.pop("auto_now") if kwargs.get("auto_now_add", False): self.auto_now_add = True kwargs.pop("auto_now_add") Field.__init__(self, *args, **kwargs)
def __init__(self, *args, **kwargs): kwargs['blank'] = True if 'default' not in kwargs: kwargs['default'] = [] if 'type' in kwargs: self._internaltype = kwargs.pop("type") Field.__init__(self, *args, **kwargs)
def ensure_field(model, name: str, field: Field): try: existing_field = model._meta.get_field(name) except FieldDoesNotExist: field.contribute_to_class(model, name) else: if not isinstance(existing_field, field.__class__): msg = ('{model} requires a field with name {name} of type {type}.'. format(model=model, name=name, type=field.__class__.__name__)) raise TypeError(msg) return field
def get_field_meta(self, field: models.Field) -> OrderedDict: # check if we need to override default get_field_meta behaviour get_field_meta = getattr(self, 'get_%s_field_meta' % field.name, None) if callable(get_field_meta): return get_field_meta(field, self.obj) sentinel = object() d = OrderedDict() for attr in self.attr_list: val = getattr(field, attr, sentinel) if val is sentinel: continue if attr in ['max_length']: if val is None: continue if attr in ['verbose_name']: val = force_text(val) d[attr] = val d['type'] = field.get_internal_type() d['required'] = self.is_required(field) if field.default != models.NOT_PROVIDED: if callable(field.default): d['default'] = field.default() else: d['default'] = field.default if hasattr(field, 'choices') and field.choices: d['choices'] = list(self.format_choices(field)) if field.related_model: if field.name not in self.no_data: user_url_getter = getattr(self, 'get_%s_dataset_url' % field.name.lower(), None) if callable(user_url_getter): d['data'] = user_url_getter(field, self.obj) elif field.name in self.dataset_urls: d['data'] = force_text(self.dataset_urls[field.name]) else: d['data'] = self.get_field_related_data(field) data_update = self.update_fields.get(field.name, {}) d.update(data_update) # check if we need to perform runtime update update_field_meta_callback = getattr(self, 'update_%s_field_meta' % field.name, None) if callable(update_field_meta_callback): d.update(update_field_meta_callback(field, self.obj)) return d
def _handle_m2m_related_field(self, related_field: Field, alias_object: Model): try: m2m_accessor_name = related_field.get_attname() except AttributeError: # get_attname does not exist for reverse m2m relations m2m_accessor_name = related_field.get_accessor_name() for obj in getattr(alias_object, m2m_accessor_name).all(): logger.debug(f'Removing {obj._meta.model.__name__}[pk={obj.pk}] ' f'from {self.model_meta.model_name}[pk={alias_object.pk}].{m2m_accessor_name}') getattr(alias_object, m2m_accessor_name).remove(obj) logger.debug(f'Adding {obj._meta.model.__name__}[pk={obj.pk}] ' f'to {self.model_meta.model_name}[pk={self.primary_object.pk}].{m2m_accessor_name}') getattr(self.primary_object, m2m_accessor_name).add(obj) self.modified_related_objects.append(obj)
def _field_type_declarations(self, field: models.Field): type_declarations = list() # If the field is relational, check that it is in the `model_pool`, and that # it has not already been "visited" (to prevent an infinite cycle). if isinstance( field, (models.ForeignKey, models.OneToOneField, models.ManyToOneRel)): if (field.related_model in self.model_pool) and (field.related_model not in self.visited_models): child_queryset_lookups = QuerysetLookups( model=field.related_model, model_pool=self.model_pool, prefixes=self.prefixes + [field.name], visited_models=self.visited_models + [self.model]) type_declarations += child_queryset_lookups.type_declarations() if not isinstance(field, models.ManyToOneRel): # This is the base lookup for the field. type_declarations.append( self._lookup_key([field.name]) + "? : " + self._lookup_type(field, None)) for lookup_str, lookup_cls in field.get_lookups().items(): type_declarations.append( self._lookup_key([field.name, lookup_str]) + "? : " + self._lookup_type(field, lookup_cls)) return type_declarations
def CountIf(field, expression, **extra): return Count( Case( When(expression, then=F(field), **extra), default=None, output_field=Field(), ))
def _handle_o2m_related_field(self, related_field: Field, alias_object: Model): reverse_o2m_accessor_name = related_field.get_accessor_name() o2m_accessor_name = related_field.field.name for obj in getattr(alias_object, reverse_o2m_accessor_name).all(): try: logger.debug( f'Attempting to set o2m field {o2m_accessor_name} on ' f'{obj._meta.model.__name__}[pk={obj.pk}] to ' f'{self.model_meta.model_name}[pk={self.primary_object.pk}] ...' ) setattr(obj, o2m_accessor_name, self.primary_object) obj.validate_unique() obj.save() logger.debug('success.') except ValidationError as e: logger.debug(f'failed. {e}') if related_field.field.null: logger.debug( f'Setting o2m field {o2m_accessor_name} on ' f'{obj._meta.model.__name__}[pk={obj.pk}] to `None`') setattr(obj, o2m_accessor_name, None) obj.save() else: logger.debug( f'Deleting {obj._meta.model.__name__}[pk={obj.pk}]') _pk = obj.pk obj.delete() obj.pk = _pk # pk is cached and re-assigned to keep the audit trail in tact self.modified_related_objects.append(obj)
def pre_save(self, model_instance, add): if not self.upload_to or (not callable(self.upload_to) and self.upload_to != self.chunks_upload_to): # this condition is verified whether "upload_to" has not been set in the # definition of field, or it has been set to the same location of the # chunks folder. # In those cases, we save some (useless) I/O operations # (i.e. deleting, and re-creating the same file twice), and # so the default FileField behaviour will be used/returned. return super(ResumableFileField, self).pre_save(model_instance, add) # if here, upload_to has been set to a different location # from the chunks_upload_to file = Field.pre_save(self, model_instance, add) if file and (not file._committed or self.chunks_upload_to in file.name): # Commit the file to storage prior to saving the model fpath = file.name.replace(settings.MEDIA_URL, self._safe_media_root()) basename = path.basename(fpath) name = self.generate_filename(model_instance, basename) new_fpath = file.storage.get_available_name( path.join(self.storage.location, name), max_length=self.max_length) basefolder = path.dirname(new_fpath) if not file.storage.exists(basefolder): makedirs(basefolder) file_move_safe(fpath, new_fpath) setattr(model_instance, self.name, name) file._committed = True file.name = name return file
def generate_value(self, field: Field, commit: bool = True) -> Any: """Call the associated generator with a field passing all required args. Generator Resolution Precedence Order: -- `field.default` - model field default value, unless explicitly overwritten during baking -- `attr_mapping` - mapping per attribute name -- `choices` -- mapping from available field choices -- `type_mapping` - mapping from user defined type associated generators -- `default_mapping` - mapping from pre-defined type associated generators `attr_mapping` and `type_mapping` can be defined easily overwriting the model. """ is_content_type_fk = isinstance(field, ForeignKey) and issubclass( self._remote_field(field).model, contenttypes.models.ContentType) # we only use default unless the field is overwritten in `self.rel_fields` if field.has_default() and field.name not in self.rel_fields: if callable(field.default): return field.default() return field.default elif field.name in self.attr_mapping: generator = self.attr_mapping[field.name] elif getattr(field, "choices"): generator = random_gen.gen_from_choices(field.choices) elif is_content_type_fk: generator = self.type_mapping[contenttypes.models.ContentType] elif generators.get(field.__class__): generator = generators.get(field.__class__) elif field.__class__ in self.type_mapping: generator = self.type_mapping[field.__class__] else: raise TypeError("%s is not supported by baker." % field.__class__) # attributes like max_length, decimal_places are taken into account when # generating the value. field._using = self._using generator_attrs = get_required_values(generator, field) if field.name in self.rel_fields: generator_attrs.update( filter_rel_attrs(field.name, **self.rel_attrs)) if not commit: generator = getattr(generator, "prepare", generator) return generator(**generator_attrs)
def clone_field_without_related_name(field: models.Field, ) -> models.Field: """Creates a clone of the given field, without a related_name.""" if isinstance(field, models.fields.related.RelatedField): # ugly hack to prevent "models not ready" error if field.swappable: field = copy(field) field.swappable = False _name, _path, args, kwargs = field.deconstruct() kwargs.pop('related_name', None) return type(field)(*args, **kwargs) else: return field.clone()
def _skip_field(self, field: Field) -> bool: from django.contrib.contenttypes.fields import GenericRelation # check for fill optional argument if isinstance(self.fill_in_optional, bool): field.fill_optional = self.fill_in_optional else: field.fill_optional = field.name in self.fill_in_optional if isinstance(field, FileField) and not self.create_files: return True # Don't Skip related _id fields defined in the iterator attributes if ((isinstance(field, OneToOneField) or isinstance(field, ForeignKey)) and hasattr(field, "attname") and field.attname in self.iterator_attrs): return False # Skip links to parent so parent is not created twice. if isinstance(field, OneToOneField) and self._remote_field(field).parent_link: return True if isinstance(field, (AutoField, GenericRelation, OrderWrt)): return True if all([ field.name not in self.model_attrs, field.name not in self.rel_fields, field.name not in self.attr_mapping, ]): # Django is quirky in that BooleanFields are always "blank", # but have no default. if not field.fill_optional and ( not issubclass(field.__class__, Field) or field.has_default() or (field.blank and not isinstance(field, BooleanField))): return True if field.name not in self.model_attrs: if field.name not in self.rel_fields and (field.null and not field.fill_optional): return True return False
def formfield(self, **kwargs): defaults = {'form_class': forms.CharField} defaults.update(kwargs) if defaults.get('widget') == admin_widgets.AdminIntegerFieldWidget: defaults['widget'] = admin_widgets.AdminTextInputWidget if defaults.get('widget') == admin_widgets.AdminBigIntegerFieldWidget: defaults['widget'] = admin_widgets.AdminTextInputWidget # noinspection PyCallByClass,PyTypeChecker return Field.formfield(self, **defaults)
def get_prep_value(self, value): """ Prepare value for database insertion """ value = Field.get_prep_value(self, value) if value is None: return value return orjson.dumps(list(map(str, value))).decode('utf-8')
def is_expandable(self, field: Field) -> bool: # if not isinstance(field, ForeignKey) or field.get_tag('enumerable'): if not isinstance(field, ForeignKey) or field.get_tag(FieldTag.ENUMERABLE): return False return ( issubclass(field.remote_field.model, CremeModel) or field.name in self.expandables )
def init_django_db(databases, debug=False): if databases is None: raise TypeError('can not find databases for Django initialization') import django from django.conf import settings django_config = { 'DEBUG': debug, 'DATABASES': databases, } settings.configure(**django_config) if hasattr(django, 'setup'): django.setup() # let django support Model.objects.filter(x__ne=3) from django.db.models import Field from djangoext.db.models.lookups import NotEqual Field.register_lookup(NotEqual)
def _handle_o2m_related_field(self, related_field: Field, alias_object: Model): reverse_o2m_accessor_name = related_field.get_accessor_name() o2m_accessor_name = related_field.field.name for obj in getattr(alias_object, reverse_o2m_accessor_name).all(): #logger.debug(f'Setting o2m field {o2m_accessor_name} on {obj._meta.model.__name__}[pk={obj.pk}] ' # f'to {self.model_meta.model_name}[pk={self.primary_object.pk}]') setattr(obj, o2m_accessor_name, self.primary_object) obj.save()
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 _handle_o2m_related_field(self, related_field: Field, alias_object: Model): if isinstance(related_field, GenericRelation): fields = related_field.remote_field.model._meta.private_fields matching_field = [f for f in fields if related_field._is_matching_generic_foreign_key(f)][0] reverse_o2m_accessor_name = related_field.get_attname() o2m_accessor_name = matching_field.name else: reverse_o2m_accessor_name = related_field.get_accessor_name() o2m_accessor_name = related_field.field.name for obj in getattr(alias_object, reverse_o2m_accessor_name).all(): try: logger.debug(f'Attempting to set o2m field {o2m_accessor_name} on ' f'{obj._meta.model.__name__}[pk={obj.pk}] to ' f'{self.model_meta.model_name}[pk={self.primary_object.pk}] ...') setattr(obj, o2m_accessor_name, self.primary_object) obj.validate_unique() obj.save() logger.debug('success.') except ValidationError as e: logger.debug(f'failed. {e}') if self.raise_validation_exception: raise if related_field.field.null: logger.debug(f'Setting o2m field {o2m_accessor_name} on ' f'{obj._meta.model.__name__}[pk={obj.pk}] to `None`') setattr(obj, o2m_accessor_name, None) obj.save() else: logger.debug(f'Deleting {obj._meta.model.__name__}[pk={obj.pk}]') _pk = obj.pk obj.delete() obj.pk = _pk # pk is cached and re-assigned to keep the audit trail in tact self.modified_related_objects.append(obj)
def _column_sql(field: Field) -> str: """ Generate the SQL required to create the given field in a CREATE TABLE statement. """ field_type = field.get_internal_type() data_types = PostgreSQLDatabaseWrapper.data_types data_type_check_constraints = PostgreSQLDatabaseWrapper.data_type_check_constraints if isinstance(field, JSONField): column_type = "jsonb" elif isinstance(field, ForeignKey): column_type = "integer" else: column_type = data_types[field_type] try: check_constraint = data_type_check_constraints[field_type] check_constraint = check_constraint % {"column": field.column} except KeyError: check_constraint = None # Interpolate any dynamic values (like max_length) column_type = column_type % field.__dict__ # Add NOT NULL if null values are not allowed if not field.null: column_type += " NOT NULL" if field.choices: # Assume that if choices is set, it's a char field and that the choices # are a list of strings that are valid values. column_type += f' CHECK ("{field.column}" IN (' column_type += ", ".join([f"'{choice}'" for _, choice in field.choices]) column_type += "))" elif check_constraint: # If the column had a check constrain defined, add that column_type += f" CHECK ({check_constraint})" return f"{field.column} {column_type}"
def pre_save(self, model_instance, add): file = Field.pre_save(self, model_instance, add) if file and (not file._committed or get_chunks_subdir() in file.name): # Commit the file to storage prior to saving the model # fpath = file.name.replace(settings.MEDIA_URL, self._safe_media_root()) # api hack needed due to the way I setup DRF. if get_chunks_subdir() not in unquote(file.name): fpath = safe_media_root() + get_chunks_subdir() + unquote(file.name) else: fpath = safe_media_root() + unquote(file.name) basename = path.basename(fpath) name = self.generate_filename(model_instance, basename) new_fpath = file.storage.get_available_name(path.join(self.storage.location, name), max_length=self.max_length) basefolder = path.dirname(new_fpath) if not file.storage.exists(basefolder): makedirs(basefolder) file_move_safe(fpath, new_fpath) setattr(model_instance, self.name, name) file._committed = True file.name = name return file
from django.db.models import Field from tools.NotEqualLookup import NotEqual Field.register_lookup(NotEqual)
from django.db.models import Field, Func, Lookup class SimilarityLookup(Lookup): lookup_name = 'similar' def as_sql(self, compiler, connection): lhs, lhs_params = self.process_lhs(compiler, connection) rhs, rhs_params = self.process_rhs(compiler, connection) params = lhs_params + rhs_params res = '{} %%> {}'.format(lhs, rhs), params return res Field.register_lookup(SimilarityLookup) class WordSimilarity(Func): template = '%(expressions)s' arg_joiner = '<<->'
from django_filters.rest_framework.backends import DjangoFilterBackend as BaseClass from django_filters import compat from django.db.models import Field LOOKUP_TYPES = Field.get_lookups().keys() class DjangoFilterBackend(BaseClass): """ Supports field filtering. This functionality requires an entry to the REST_FRAMEWORK settings dictionary in settings.py: 'DEFAULT_FILTER_BACKENDS': ('drf_jsonapi.backends.DjangoFilterBackend') """ def get_schema_fields(self, view): """ Retrieve a list of Field objects from a view :param self: This object instance :param view: A Django View :returns: A list of CoreApi Field objects """ filter_class = getattr(view, 'filter_class', None) fields = [] if not filter_class: return fields for field_name, field in filter_class.base_filters.items():
class ILike(IContains): lookup_name = 'ilike' def process_lhs(self, qn, connection): lhs_sql, params = super(ILike, self).process_lhs(qn, connection) backend_name = backend.__name__ if 'postgres' in backend_name or \ 'oracle' in backend_name: lhs_sql = 'UPPER(%s)' % lhs_sql return (lhs_sql, params) def get_rhs_op(self, connection, rhs): return connection.operators['icontains'] % rhs Field.register_lookup(Like) Field.register_lookup(ILike) else: from django.db import connection from django.db.models.fields import Field, subclassing from django.db.models.sql.constants import QUERY_TERMS if isinstance(QUERY_TERMS, set): QUERY_TERMS.add('like') QUERY_TERMS.add('ilike') else: QUERY_TERMS['like'] = None QUERY_TERMS['ilike'] = None connection.operators['like'] = connection.operators['contains']
def __init__(self, *args, **kwargs): kwargs['blank'] = True Field.__init__(self, *args, **kwargs)
def __init__(self, *args, **kwargs): assert kwargs.get('primary_key', False) is True,\ "%ss must have primary_key=True." % self.__class__.__name__ kwargs['blank'] = True self.length = kwargs.pop("length",9) Field.__init__(self, *args, **kwargs)
def formfield(self, **kwargs): defaults = {'max_length': self.max_length, 'widget': RubricateWidget} kwargs.update(defaults) return Field.formfield(self, **kwargs)
def __init__(self, *args, **kwargs): Field.__init__(self, validators = [arrayvalidator], **kwargs)
def __init__(self, verbose_name=None, name=None, separator=default_separator, **kwargs): self.separator = separator Field.__init__(self, verbose_name, name, **kwargs)
return '%s = %s * %s' % (lhs, rhs, dimension), params return CoordinateLookup class CoordinateValue(Transform): lookup_name = 'coord' def as_sql(self, compiler, connection): lhs, params = compiler.compile(self.lhs) return "%s" % lhs, params @property def output_field(self): return CoordinatesField() Field.register_lookup(CoordinateValue) p = Product.objects.get(stock_price__coord__x2=500) print(p) #********************************************************************** #Expressions from discount.models import Product from django.db.models import F, Q, Count, Value, DateTimeField, ExpressionWrapper, Func, Aggregate, IntegerField, CharField from django.db.models.functions import Length #??? from datetime import date #https://docs.djangoproject.com/en/1.8/ref/models/expressions/
def __init__(self, *args, **kwargs): assert kwargs.get('primary_key', False) is True,\ "%ss must have primary_key=True." % self.__class__.__name__ kwargs['blank'] = True self.length = kwargs.pop("length", 9) Field.__init__(self, *args, **kwargs)
tipo = models.CharField(max_length=127) filtro = models.ManyToManyField(Filtro, blank=True) color = models.CharField(max_length=127) uuid = models.UUIDField( # usado por el api para buscar el registro db_index=True, default=uuid_lib.uuid4, editable=False) class Meta: unique_together = ('material', 'tipo', 'color') def save(self, *args, **kwargs): self.material = self.material.title() self.tipo = self.tipo.title() self.color = self.color.title() super(Lente, self).save(*args, **kwargs) class Quotient(Lookup): lookup_name = 'qo' def as_sql(self, compiler, connection): lhs, lhs_params = self.process_lhs(compiler, connection) rhs, rhs_params = self.process_rhs(compiler, connection) div = [pow(10, 8 - get_count_digits(int(rhs_params[0])))] params = lhs_params + div + rhs_params return '{} / {} = {}'.format(lhs, '%s', rhs), params Field.register_lookup(Quotient)
from django.contrib import admin from publiapp_api import models from django.db.models import Field admin.site.register(models.UserProfile) admin.site.register(models.Constantes) admin.site.register(models.Anuncio) admin.site.register(models.DetalleAnuncio) admin.site.register(models.Precio) admin.site.register(models.Categoria) admin.site.register(models.Resenia) admin.site.register(models.Rol) admin.site.register(models.Ubigeo) admin.site.register(models.Anunciante) admin.site.register(models.Imagen) admin.site.register(models.LogBusqueda) admin.site.register(models.LogDetalleAnuncio) admin.site.register(models.LogContacto) admin.site.register(models.ArticuloOcacional) Field.register_lookup(models.NotEqual)