def _verify_field_names(fields, valid_fields, filter_name):
    if fields:
        invalid_field_names = fields - valid_fields
        if invalid_field_names:
            error = 'Unknown fields in "%s" filter: %s' % (filter_name, ', '.join(invalid_field_names))
            raise FieldError(error)
Exemple #2
0
    def _setup_joins_with_translation(self,
                                      names,
                                      opts,
                                      alias,
                                      dupe_multis,
                                      allow_many=True,
                                      allow_explicit_fk=False,
                                      can_reuse=None,
                                      negate=False,
                                      process_extras=True):
        """
        This is based on a full copy of Query.setup_joins because
        currently I see no way to handle it differently.

        TO DO: there might actually be a way, by splitting a single
        multi-name setup_joins call into separate calls.  Check it.

        -- [email protected]

        Compute the necessary table joins for the passage through the fields
        given in 'names'. 'opts' is the Options class for the current model
        (which gives the table we are joining to), 'alias' is the alias for the
        table we are joining to. If dupe_multis is True, any many-to-many or
        many-to-one joins will always create a new alias (necessary for
        disjunctive filters).

        Returns the final field involved in the join, the target database
        column (used for any 'where' constraint), the final 'opts' value and the
        list of tables joined.
        """
        joins = [alias]
        last = [0]
        dupe_set = set()
        exclusions = set()
        extra_filters = []
        for pos, name in enumerate(names):
            try:
                exclusions.add(int_alias)
            except NameError:
                pass
            exclusions.add(alias)
            last.append(len(joins))
            if name == 'pk':
                name = opts.pk.name

            try:
                field, model, direct, m2m = opts.get_field_by_name(name)
            except FieldDoesNotExist:
                for f in opts.fields:
                    if allow_explicit_fk and name == f.attname:
                        # XXX: A hack to allow foo_id to work in values() for
                        # backwards compatibility purposes. If we dropped that
                        # feature, this could be removed.
                        field, model, direct, m2m = opts.get_field_by_name(
                            f.name)
                        break
                else:
                    names = opts.get_all_field_names()
                    raise FieldError("Cannot resolve keyword %r into field. "
                                     "Choices are: %s" %
                                     (name, ", ".join(names)))

            if not allow_many and (m2m or not direct):
                for alias in joins:
                    self.unref_alias(alias)
                raise MultiJoin(pos + 1)

            #NOTE: Start Django Multilingual specific code
            if hasattr(opts, 'translation_model'):
                translation_opts = opts.translation_model._meta
                if model == opts.translation_model:
                    language_id = translation_opts.translated_fields[name][1]
                    if language_id is None:
                        language_id = get_default_language()
                    #TODO: check alias
                    master_table_name = opts.db_table
                    trans_table_alias = get_translation_table_alias(
                        model._meta.db_table, language_id)
                    new_table = (master_table_name + "__" + trans_table_alias)
                    qn = self.quote_name_unless_alias
                    qn2 = self.connection.ops.quote_name
                    trans_join = (
                        'LEFT JOIN %s AS %s ON ((%s.master_id = %s.%s) AND (%s.language_id = %s))'
                        % (qn2(model._meta.db_table), qn2(new_table),
                           qn2(new_table), qn(master_table_name),
                           qn2(model._meta.pk.column), qn2(new_table),
                           language_id))
                    self.extra_join[new_table] = trans_join
                    target = field
                    continue
                    #NOTE: End Django Multilingual specific code
            elif model:
                # The field lives on a base class of the current model.
                for int_model in opts.get_base_chain(model):
                    lhs_col = opts.parents[int_model].column
                    dedupe = lhs_col in opts.duplicate_targets
                    if dedupe:
                        exclusions.update(
                            self.dupe_avoidance.get((id(opts), lhs_col), ()))
                        dupe_set.add((opts, lhs_col))
                    opts = int_model._meta
                    alias = self.join(
                        (alias, opts.db_table, lhs_col, opts.pk.column),
                        exclusions=exclusions)
                    joins.append(alias)
                    exclusions.add(alias)
                    for (dupe_opts, dupe_col) in dupe_set:
                        self.update_dupe_avoidance(dupe_opts, dupe_col, alias)
            cached_data = opts._join_cache.get(name)
            orig_opts = opts
            dupe_col = direct and field.column or field.field.column
            dedupe = dupe_col in opts.duplicate_targets
            if dupe_set or dedupe:
                if dedupe:
                    dupe_set.add((opts, dupe_col))
                exclusions.update(
                    self.dupe_avoidance.get((id(opts), dupe_col), ()))

            if process_extras and hasattr(field, 'extra_filters'):
                extra_filters.extend(field.extra_filters(names, pos, negate))
            if direct:
                if m2m:
                    # Many-to-many field defined on the current model.
                    if cached_data:
                        (table1, from_col1, to_col1, table2, from_col2,
                         to_col2, opts, target) = cached_data
                    else:
                        table1 = field.m2m_db_table()
                        from_col1 = opts.pk.column
                        to_col1 = field.m2m_column_name()
                        opts = field.rel.to._meta
                        table2 = opts.db_table
                        from_col2 = field.m2m_reverse_name()
                        to_col2 = opts.pk.column
                        target = opts.pk
                        orig_opts._join_cache[name] = (table1, from_col1,
                                                       to_col1, table2,
                                                       from_col2, to_col2,
                                                       opts, target)

                    int_alias = self.join((alias, table1, from_col1, to_col1),
                                          dupe_multis,
                                          exclusions,
                                          nullable=True,
                                          reuse=can_reuse)
                    if int_alias == table2 and from_col2 == to_col2:
                        joins.append(int_alias)
                        alias = int_alias
                    else:
                        alias = self.join(
                            (int_alias, table2, from_col2, to_col2),
                            dupe_multis,
                            exclusions,
                            nullable=True,
                            reuse=can_reuse)
                        joins.extend([int_alias, alias])
                elif field.rel:
                    # One-to-one or many-to-one field
                    if cached_data:
                        (table, from_col, to_col, opts, target) = cached_data
                    else:
                        opts = field.rel.to._meta
                        target = field.rel.get_related_field()
                        table = opts.db_table
                        from_col = field.column
                        to_col = target.column
                        orig_opts._join_cache[name] = (table, from_col, to_col,
                                                       opts, target)

                    alias = self.join((alias, table, from_col, to_col),
                                      exclusions=exclusions,
                                      nullable=field.null)
                    joins.append(alias)
                else:
                    # Non-relation fields.
                    target = field
                    break
            else:
                orig_field = field
                field = field.field
                if m2m:
                    # Many-to-many field defined on the target model.
                    if cached_data:
                        (table1, from_col1, to_col1, table2, from_col2,
                         to_col2, opts, target) = cached_data
                    else:
                        table1 = field.m2m_db_table()
                        from_col1 = opts.pk.column
                        to_col1 = field.m2m_reverse_name()
                        opts = orig_field.opts
                        table2 = opts.db_table
                        from_col2 = field.m2m_column_name()
                        to_col2 = opts.pk.column
                        target = opts.pk
                        orig_opts._join_cache[name] = (table1, from_col1,
                                                       to_col1, table2,
                                                       from_col2, to_col2,
                                                       opts, target)

                    int_alias = self.join((alias, table1, from_col1, to_col1),
                                          dupe_multis,
                                          exclusions,
                                          nullable=True,
                                          reuse=can_reuse)
                    alias = self.join((int_alias, table2, from_col2, to_col2),
                                      dupe_multis,
                                      exclusions,
                                      nullable=True,
                                      reuse=can_reuse)
                    joins.extend([int_alias, alias])
                else:
                    # One-to-many field (ForeignKey defined on the target model)
                    if cached_data:
                        (table, from_col, to_col, opts, target) = cached_data
                    else:
                        local_field = opts.get_field_by_name(
                            field.rel.field_name)[0]
                        opts = orig_field.opts
                        table = opts.db_table
                        from_col = local_field.column
                        to_col = field.column
                        target = opts.pk
                        orig_opts._join_cache[name] = (table, from_col, to_col,
                                                       opts, target)

                    alias = self.join((alias, table, from_col, to_col),
                                      dupe_multis,
                                      exclusions,
                                      nullable=True,
                                      reuse=can_reuse)
                    joins.append(alias)

            for (dupe_opts, dupe_col) in dupe_set:
                try:
                    self.update_dupe_avoidance(dupe_opts, dupe_col, int_alias)
                except NameError:
                    self.update_dupe_avoidance(dupe_opts, dupe_col, alias)

        if pos != len(names) - 1:
            raise FieldError("Join on field %r not permitted." % name)

        return field, target, opts, joins, last, extra_filters
Exemple #3
0
    def __new__(cls, name, bases, attrs):
        super_new = super(ModelBase, cls).__new__

        # six.with_metaclass() inserts an extra class called 'NewBase' in the
        # inheritance tree: Model -> NewBase -> object. But the initialization
        # should be executed only once for a given model class.

        # attrs will never be empty for classes declared in the standard way
        # (ie. with the `class` keyword). This is quite robust.
        if name == 'NewBase' and attrs == {}:
            return super_new(cls, name, bases, attrs)

        # Also ensure initialization is only performed for subclasses of Model
        # (excluding Model class itself).
        parents = [
            b for b in bases if isinstance(b, ModelBase)
            and not (b.__name__ == 'NewBase' and b.__mro__ == (b, object))
        ]
        if not parents:
            return super_new(cls, name, bases, attrs)

        # Create the class.
        module = attrs.pop('__module__')
        new_class = super_new(cls, name, bases, {'__module__': module})
        attr_meta = attrs.pop('Meta', None)
        abstract = getattr(attr_meta, 'abstract', False)
        if not attr_meta:
            meta = getattr(new_class, 'Meta', None)
        else:
            meta = attr_meta
        base_meta = getattr(new_class, '_meta', None)

        if getattr(meta, 'app_label', None) is None:
            # Figure out the app_label by looking one level up.
            # For 'django.contrib.sites.models', this would be 'sites'.
            model_module = sys.modules[new_class.__module__]
            kwargs = {"app_label": model_module.__name__.split('.')[-2]}
        else:
            kwargs = {}

        new_class.add_to_class('_meta', Options(meta, **kwargs))
        if not abstract:
            new_class.add_to_class(
                'DoesNotExist',
                subclass_exception(
                    str('DoesNotExist'),
                    tuple(x.DoesNotExist for x in parents
                          if hasattr(x, '_meta') and not x._meta.abstract)
                    or (ObjectDoesNotExist, ),
                    module,
                    attached_to=new_class))
            new_class.add_to_class(
                'MultipleObjectsReturned',
                subclass_exception(
                    str('MultipleObjectsReturned'),
                    tuple(x.MultipleObjectsReturned for x in parents
                          if hasattr(x, '_meta') and not x._meta.abstract)
                    or (MultipleObjectsReturned, ),
                    module,
                    attached_to=new_class))
            if base_meta and not base_meta.abstract:
                # Non-abstract child classes inherit some attributes from their
                # non-abstract parent (unless an ABC comes before it in the
                # method resolution order).
                if not hasattr(meta, 'ordering'):
                    new_class._meta.ordering = base_meta.ordering
                if not hasattr(meta, 'get_latest_by'):
                    new_class._meta.get_latest_by = base_meta.get_latest_by

        is_proxy = new_class._meta.proxy

        # If the model is a proxy, ensure that the base class
        # hasn't been swapped out.
        if is_proxy and base_meta and base_meta.swapped:
            raise TypeError("%s cannot proxy the swapped model '%s'." %
                            (name, base_meta.swapped))

        if getattr(new_class, '_default_manager', None):
            if not is_proxy:
                # Multi-table inheritance doesn't inherit default manager from
                # parents.
                new_class._default_manager = None
                new_class._base_manager = None
            else:
                # Proxy classes do inherit parent's default manager, if none is
                # set explicitly.
                new_class._default_manager = new_class._default_manager._copy_to_model(
                    new_class)
                new_class._base_manager = new_class._base_manager._copy_to_model(
                    new_class)

        # Bail out early if we have already created this class.
        m = get_model(new_class._meta.app_label,
                      name,
                      seed_cache=False,
                      only_installed=False)
        if m is not None:
            return m

        # Add all attributes to the class.
        for obj_name, obj in attrs.items():
            new_class.add_to_class(obj_name, obj)

        # All the fields of any type declared on this model
        new_fields = new_class._meta.local_fields + \
                     new_class._meta.local_many_to_many + \
                     new_class._meta.virtual_fields
        field_names = set([f.name for f in new_fields])

        # Basic setup for proxy models.
        if is_proxy:
            base = None
            for parent in [cls for cls in parents if hasattr(cls, '_meta')]:
                if parent._meta.abstract:
                    if parent._meta.fields:
                        raise TypeError(
                            "Abstract base class containing model fields not permitted for proxy model '%s'."
                            % name)
                    else:
                        continue
                if base is not None:
                    raise TypeError(
                        "Proxy model '%s' has more than one non-abstract model base class."
                        % name)
                else:
                    base = parent
            if base is None:
                raise TypeError(
                    "Proxy model '%s' has no non-abstract model base class." %
                    name)
            if (new_class._meta.local_fields
                    or new_class._meta.local_many_to_many):
                raise FieldError("Proxy model '%s' contains model fields." %
                                 name)
            new_class._meta.setup_proxy(base)
            new_class._meta.concrete_model = base._meta.concrete_model
        else:
            new_class._meta.concrete_model = new_class

        # Do the appropriate setup for any model parents.
        o2o_map = dict([(f.rel.to, f) for f in new_class._meta.local_fields
                        if isinstance(f, OneToOneField)])

        for base in parents:
            original_base = base
            if not hasattr(base, '_meta'):
                # Things without _meta aren't functional models, so they're
                # uninteresting parents.
                continue

            parent_fields = base._meta.local_fields + base._meta.local_many_to_many
            # Check for clashes between locally declared fields and those
            # on the base classes (we cannot handle shadowed fields at the
            # moment).
            for field in parent_fields:
                if field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '
                                     'with field of similar name from '
                                     'base class %r' %
                                     (field.name, name, base.__name__))
            if not base._meta.abstract:
                # Concrete classes...
                base = base._meta.concrete_model
                if base in o2o_map:
                    field = o2o_map[base]
                elif not is_proxy:
                    attr_name = '%s_ptr' % base._meta.model_name
                    field = OneToOneField(base,
                                          name=attr_name,
                                          auto_created=True,
                                          parent_link=True)
                    new_class.add_to_class(attr_name, field)
                else:
                    field = None
                new_class._meta.parents[base] = field
            else:
                # .. and abstract ones.
                for field in parent_fields:
                    new_class.add_to_class(field.name, copy.deepcopy(field))

                # Pass any non-abstract parent classes onto child.
                new_class._meta.parents.update(base._meta.parents)

            # Inherit managers from the abstract base classes.
            new_class.copy_managers(base._meta.abstract_managers)

            # Proxy models inherit the non-abstract managers from their base,
            # unless they have redefined any of them.
            if is_proxy:
                new_class.copy_managers(original_base._meta.concrete_managers)

            # Inherit virtual fields (like GenericForeignKey) from the parent
            # class
            for field in base._meta.virtual_fields:
                if base._meta.abstract and field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '\
                                     'with field of similar name from '\
                                     'abstract base class %r' % \
                                        (field.name, name, base.__name__))
                new_class.add_to_class(field.name, copy.deepcopy(field))

        if abstract:
            # Abstract base models can't be instantiated and don't appear in
            # the list of models for an app. We do the final setup for them a
            # little differently from normal models.
            attr_meta.abstract = False
            new_class.Meta = attr_meta
            return new_class

        new_class._prepare()
        register_models(new_class._meta.app_label, new_class)

        # Because of the way imports happen (recursively), we may or may not be
        # the first time this model tries to register with the framework. There
        # should only be one class for each model, so we always return the
        # registered version.
        return get_model(new_class._meta.app_label,
                         name,
                         seed_cache=False,
                         only_installed=False)
Exemple #4
0
def exportMeasurementData(req):
    """
    Returns the measurement data from a list of reservoirs in Excel compatible format (csv or xls)
    """

    availableFormats = ['csv', 'xls']
    if not 'format' in req.GET or \
    not req.GET['format'] in availableFormats or \
    not 'dateFrom' in req.GET or \
    not 'dateUntil' in req.GET or \
    not 'reservoirs' in req.GET :
        print('[exportMeasurementData] missing parameters')
        raise FieldError('Pedido Inválido')

    # names that will be shown in the header of Excel table
    dataColumns = [
        'Reservatório', 'Data e Hora', 'Nivel de Água', 'pH', 'Condutividade',
        'Salinidade', 'TDS'
    ]
    # the attributes to export
    attrKeys = [
        'reservoir__res_id', 'dateTime', 'waterLevel', 'pH', 'conductivity',
        'salinity', 'tds'
    ]

    try:
        dtFrom = timezone.datetime.strptime(req.GET['dateFrom'], '%Y-%m-%d')
        dtUntil = timezone.datetime.strptime(req.GET['dateUntil'], '%Y-%m-%d')
        data = Measurement.objects \
            .filter(dateTime__gte=dtFrom, dateTime__lte=dtUntil) \
            .values(*attrKeys)

        if req.GET['reservoirs'] != 'all' or req.GET['reservoirs'] == '':
            data.filter(reservoir__res_id__in=req.GET['reservoirs'].split(','))

        # change dates to string values
        for value in data:
            value['dateTime'] = value['dateTime'].strftime('%d-%m-%Y %H:%M')

    except Exception as e:
        print('[exportMeasurementData] failed to read data: {}'.format(e))
        raise SuspiciousOperation('Não foi possivel ler os dados')

    if req.GET['format'] == 'csv':
        response = HttpResponse(content_type='text/csv')
        response[
            'Content-Disposition'] = 'attachement; filename="exported_data.csv"'
        writer = csv.writer(response)
        writer.writerow(dataColumns)
        dataAsValuesList = data.values_list(*attrKeys)
        for values in dataAsValuesList:
            writer.writerow(values)

        return response

    else:  # format == 'xls'
        response = HttpResponse(content_type='text/ms-excel')
        response[
            'Content-Disposition'] = 'attachement; filename="exported_data.xls"'
        writer = xlwt.Workbook(encoding='utf-8')
        sheet = writer.add_sheet('Medições')

        row = 0

        headerFont = xlwt.XFStyle()
        headerFont.font.bold
        # write the table header
        for col in range(len(dataColumns)):
            sheet.write(row, col, dataColumns[col], headerFont)

        bodyFont = xlwt.XFStyle()
        # write the body
        for values in data:
            row += 1
            for col in range(len(values)):
                sheet.write(row, col, values[attrKeys[col]], bodyFont)

        writer.save(response)
        return response
Exemple #5
0
 def previous(self, field):
     """Returns currently saved value of given field"""
     if field in self.fields:
         return self.saved_data.get(field)
     else:
         raise FieldError('field "%s" not tracked' % field)
Exemple #6
0
    def __new__(cls, name, bases, attrs):
        super_new = super(ModelBase, cls).__new__
        parents = [b for b in bases if isinstance(b, ModelBase)]
        if not parents:
            # If this isn't a subclass of Model, don't do anything special.
            return super_new(cls, name, bases, attrs)

        # Create the class.
        module = attrs.pop('__module__')
        new_class = super_new(cls, name, bases, {'__module__': module})
        attr_meta = attrs.pop('Meta', None)
        abstract = getattr(attr_meta, 'abstract', False)
        if not attr_meta:
            meta = getattr(new_class, 'Meta', None)
        else:
            meta = attr_meta
        base_meta = getattr(new_class, '_meta', None)

        if getattr(meta, 'app_label', None) is None:
            # Figure out the app_label by looking one level up.
            # For 'django.contrib.sites.models', this would be 'sites'.
            model_module = sys.modules[new_class.__module__]
            kwargs = {"app_label": model_module.__name__.split('.')[-2]}
        else:
            kwargs = {}

        new_class.add_to_class('_meta', Options(meta, **kwargs))
        if not abstract:
            new_class.add_to_class(
                'DoesNotExist',
                subclass_exception('DoesNotExist', ObjectDoesNotExist, module))
            new_class.add_to_class(
                'MultipleObjectsReturned',
                subclass_exception('MultipleObjectsReturned',
                                   MultipleObjectsReturned, module))
            if base_meta and not base_meta.abstract:
                # Non-abstract child classes inherit some attributes from their
                # non-abstract parent (unless an ABC comes before it in the
                # method resolution order).
                if not hasattr(meta, 'ordering'):
                    new_class._meta.ordering = base_meta.ordering
                if not hasattr(meta, 'get_latest_by'):
                    new_class._meta.get_latest_by = base_meta.get_latest_by

        if getattr(new_class, '_default_manager', None):
            new_class._default_manager = None
            new_class._base_manager = None

        # Bail out early if we have already created this class.
        m = get_model(new_class._meta.app_label, name, False)
        if m is not None:
            return m

        # Add all attributes to the class.
        for obj_name, obj in attrs.items():
            new_class.add_to_class(obj_name, obj)

        # Do the appropriate setup for any model parents.
        o2o_map = dict([(f.rel.to, f) for f in new_class._meta.local_fields
                        if isinstance(f, OneToOneField)])
        for base in parents:
            if not hasattr(base, '_meta'):
                # Things without _meta aren't functional models, so they're
                # uninteresting parents.
                continue

            # All the fields of any type declared on this model
            new_fields = new_class._meta.local_fields + \
                         new_class._meta.local_many_to_many + \
                         new_class._meta.virtual_fields
            field_names = set([f.name for f in new_fields])

            parent_fields = base._meta.local_fields + base._meta.local_many_to_many
            # Check for clashes between locally declared fields and those
            # on the base classes (we cannot handle shadowed fields at the
            # moment).
            for field in parent_fields:
                if field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '
                                     'with field of similar name from '
                                     'base class %r' %
                                     (field.name, name, base.__name__))
            if not base._meta.abstract:
                # Concrete classes...
                if base in o2o_map:
                    field = o2o_map[base]
                else:
                    attr_name = '%s_ptr' % base._meta.module_name
                    field = OneToOneField(base,
                                          name=attr_name,
                                          auto_created=True,
                                          parent_link=True)
                    new_class.add_to_class(attr_name, field)
                new_class._meta.parents[base] = field

            else:
                # .. and abstract ones.
                for field in parent_fields:
                    new_class.add_to_class(field.name, copy.deepcopy(field))

                # Pass any non-abstract parent classes onto child.
                new_class._meta.parents.update(base._meta.parents)

            # Inherit managers from the abstract base classes.
            base_managers = base._meta.abstract_managers
            base_managers.sort()
            for _, mgr_name, manager in base_managers:
                val = getattr(new_class, mgr_name, None)
                if not val or val is manager:
                    new_manager = manager._copy_to_model(new_class)
                    new_class.add_to_class(mgr_name, new_manager)

            # Inherit virtual fields (like GenericForeignKey) from the parent
            # class
            for field in base._meta.virtual_fields:
                if base._meta.abstract and field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '\
                                     'with field of similar name from '\
                                     'abstract base class %r' % \
                                        (field.name, name, base.__name__))
                new_class.add_to_class(field.name, copy.deepcopy(field))

        if abstract:
            # Abstract base models can't be instantiated and don't appear in
            # the list of models for an app. We do the final setup for them a
            # little differently from normal models.
            attr_meta.abstract = False
            new_class.Meta = attr_meta
            return new_class

        new_class._prepare()
        register_models(new_class._meta.app_label, new_class)

        # Because of the way imports happen (recursively), we may or may not be
        # the first time this model tries to register with the framework. There
        # should only be one class for each model, so we always return the
        # registered version.
        return get_model(new_class._meta.app_label, name, False)
Exemple #7
0
 def as_sql(self, qn, connection):
     raise FieldError("Unsupported lookup '%s'" % self.lookup_name)
Exemple #8
0
    def as_sql(self):
        """
        Creates the SQL for this query. Returns the SQL string and list of
        parameters.
        """
        self.pre_sql_setup()
        if not self.query.values:
            return '', ()
        table = self.query.base_table
        qn = self.quote_name_unless_alias
        result = ['UPDATE %s' % qn(table)]
        result.append('SET')
        values, update_params = [], []
        for field, model, val in self.query.values:
            self.name = name = field.column
            if hasattr(val, 'alter_name'):
                self.name = name = val.alter_name(name, qn)
                qn = no_quote_name
                val = val.value
            if hasattr(val, 'resolve_expression'):
                val = val.resolve_expression(self.query,
                                             allow_joins=False,
                                             for_save=True)
                if val.contains_aggregate:
                    raise FieldError(
                        "Aggregate functions are not allowed in this query")
            elif hasattr(val, 'prepare_database_save'):
                if field.remote_field:
                    val = field.get_db_prep_save(
                        val.prepare_database_save(field),
                        connection=self.connection,
                    )
                else:
                    raise TypeError(
                        "Tried to update field %s with a model instance, %r. "
                        "Use a value compatible with %s." %
                        (field, val, field.__class__.__name__))
            else:
                val = field.get_db_prep_save(val, connection=self.connection)

            # Getting the placeholder for the field.
            if hasattr(field, 'get_placeholder'):
                placeholder = field.get_placeholder(val, self, self.connection)
            else:
                placeholder = '%s'
            self.placeholder = placeholder
            if hasattr(val, 'as_sql'):
                sql, params = self.compile(val)
                values.append('%s = %s' % (qn(name), sql))
                update_params.extend(params)
            elif val is not None:
                values.append('%s = %s' % (qn(name), placeholder))
                update_params.append(val)
            else:
                values.append('%s = NULL' % qn(name))
        if not values:
            return '', ()
        result.append(', '.join(values))
        where, params = self.compile(self.query.where)
        if where:
            result.append('WHERE %s' % where)
        return ' '.join(result), tuple(update_params + params)
def object_relation_mixin_factory(
    prefix=None,
    prefix_verbose=None,
    add_related_name=False,
    limit_content_type_choices_to={},
    limit_object_choices_to={},
    is_required=False,
):
    """
    returns a mixin class for generic foreign keys using
    "Content type - object Id" with dynamic field names.
    This function is just a class generator

    Parameters:
    prefix : a prefix, which is added in front of the fields
    prefix_verbose :    a verbose name of the prefix, used to
                        generate a title for the field column
                        of the content object in the Admin.
    add_related_name :  a boolean value indicating, that a
                        related name for the generated content
                        type foreign key should be added. This
                        value should be true, if you use more
                        than one ObjectRelationMixin in your model.

    The model fields are created like this:

    <<prefix>>_content_type :   Field name for the "content type"
    <<prefix>>_object_id :      Field name for the "object Id"
    <<prefix>>_content_object : Field name for the "content object"

    """
    if prefix:
        p = "%s_" % prefix
    else:
        p = ""

    content_type_field = "%scontent_type" % p
    object_id_field = "%sobject_id" % p
    content_object_field = "%scontent_object" % p

    class TheClass(models.Model):
        class Meta:
            abstract = True

    if add_related_name:
        if not prefix:
            raise FieldError(
                "if add_related_name is set to True, a prefix must be given")
        related_name = prefix
    else:
        related_name = None

    content_type = models.ForeignKey(
        ContentType,
        verbose_name=(prefix_verbose
                      and _("%s's type (model)") % prefix_verbose
                      or _("Related object's type (model)")),
        related_name=related_name,
        blank=not is_required,
        null=not is_required,
        help_text=
        _("Please select the type (model) for the relation, you want to build."
          ),
        limit_choices_to=limit_content_type_choices_to,
    )

    object_id = models.CharField(
        (prefix_verbose or _("Related object")),
        blank=not is_required,
        null=False,
        help_text=_("Please enter the ID of the related object."),
        max_length=255,
        default="",  # for south migrations
    )
    object_id.limit_choices_to = limit_object_choices_to
    # can be retrieved by MyModel._meta.get_field("object_id").limit_choices_to
    content_object = GenericForeignKey(
        ct_field=content_type_field,
        fk_field=object_id_field,
    )

    TheClass.add_to_class(content_type_field, content_type)
    TheClass.add_to_class(object_id_field, object_id)
    TheClass.add_to_class(content_object_field, content_object)

    return TheClass
Exemple #10
0
def format_field_value(field, val, conn, cast_type=False):
    # type: (Field, Any, TDatabase, bool) -> Tuple[str, Tuple[Any]]
    """
    Formats value, according to field rules
    :param field: Django field to take format from
    :param val: Value to format
    :param conn: Connection used to update data
    :param cast_type: Adds type casting to sql if flag is True
    :return: A tuple: sql, replacing value in update and a tuple of parameters to pass to cursor
    """
    # This content is a part, taken from django.db.models.sql.compiler.SQLUpdateCompiler.as_sql()
    # And modified for our needs
    query = UpdateQuery(field.model)
    compiler = query.get_compiler(connection=conn)
    HStoreField = import_pg_field_or_dummy('HStoreField', hstore_available)

    if hasattr(val, 'resolve_expression'):
        val = val.resolve_expression(query, allow_joins=False, for_save=True)
        if val.contains_aggregate:
            raise FieldError(
                'Aggregate functions are not allowed in this query '
                '(%s=%r).' % (field.name, val))
        if val.contains_over_clause:
            raise FieldError(
                'Window expressions are not allowed in this query '
                '(%s=%r).' % (field.name, val))
    elif hasattr(val, 'prepare_database_save'):
        if field.remote_field:
            val = field.get_db_prep_save(val.prepare_database_save(field),
                                         connection=conn)
        else:
            raise TypeError(
                "Tried to update field %s with a model instance, %r. "
                "Use a value compatible with %s." %
                (field, val, field.__class__.__name__))
    elif isinstance(field, HStoreField):
        # Django before 1.10 doesn't convert HStoreField values to string automatically
        # Which causes a bug in cursor.execute(). Let's do it here
        if isinstance(val, dict):
            val = hstore_serialize(val)
        val = field.get_db_prep_save(val, connection=conn)
    else:
        val = field.get_db_prep_save(val, connection=conn)

    # Getting the placeholder for the field.
    if hasattr(field, 'get_placeholder'):
        placeholder = field.get_placeholder(val, compiler, conn)

        # django 2.2 adds ::serial[] to placeholders for arrays...
        placeholder = placeholder.split('::')[0]
    else:
        placeholder = '%s'

    if hasattr(val, 'as_sql'):
        sql, update_params = compiler.compile(val)
        value = placeholder % sql
    elif val is not None:
        value, update_params = placeholder, (val, )
    else:
        value, update_params = 'NULL', tuple()

    if cast_type:
        value = 'CAST(%s AS %s)' % (value, get_field_db_type(field, conn))

    return value, tuple(update_params)
Exemple #11
0
    def __new__(cls, name, bases, attrs):
        """
        Django 1.3 fix, that removes all Meta.fields and Meta.exclude
        fieldnames that are in the translatable model. This ensures
        that the superclass' init method doesnt throw a validation
        error
        """
        fields = []
        exclude = []
        fieldsets = []
        if "Meta" in attrs:
            meta = attrs["Meta"]
            if getattr(meta, "fieldsets", False):
                fieldsets = meta.fieldsets
                meta.fieldsets = []
            if getattr(meta, "fields", False):
                fields = meta.fields
                meta.fields = []
            if getattr(meta, "exclude", False):
                exclude = meta.exclude
                meta.exclude = []
        # End 1.3 fix

        super_new = super(TranslatableModelFormMetaclass, cls).__new__

        formfield_callback = attrs.pop('formfield_callback', None)
        declared_fields = get_declared_fields(bases, attrs, False)
        new_class = super_new(cls, name, bases, attrs)

        # Start 1.3 fix
        if fields:
            new_class.Meta.fields = fields
        if exclude:
            new_class.Meta.exclude = exclude
        if fieldsets:
            new_class.Meta.fieldsets = fieldsets
        # End 1.3 fix

        if not getattr(new_class, "Meta", None):

            class Meta:
                exclude = ['language_code']

            new_class.Meta = Meta
        elif not getattr(new_class.Meta, 'exclude', None):
            new_class.Meta.exclude = ['language_code']
        elif getattr(new_class.Meta, 'exclude', False):
            if 'language_code' not in new_class.Meta.exclude:
                new_class.Meta.exclude.append("language_code")

        if 'Media' not in attrs:
            new_class.media = media_property(new_class)
        opts = new_class._meta = ModelFormOptions(
            getattr(new_class, 'Meta', attrs.get('Meta', None)))
        if opts.model:
            # bail out if a wrong model uses this form class
            if not issubclass(opts.model, TranslatableModel):
                raise TypeError(
                    "Only TranslatableModel subclasses may use TranslatableModelForm"
                )
            mopts = opts.model._meta

            shared_fields = mopts.get_all_field_names()

            # split exclude and include fieldnames into shared and translated
            sfieldnames = [
                field for field in opts.fields or [] if field in shared_fields
            ]
            tfieldnames = [
                field for field in opts.fields or []
                if field not in shared_fields
            ]
            sexclude = [
                field for field in opts.exclude or [] if field in shared_fields
            ]
            texclude = [
                field for field in opts.exclude or []
                if field not in shared_fields
            ]

            # required by fields_for_model
            if not sfieldnames:
                sfieldnames = None if not fields else []
            if not tfieldnames:
                tfieldnames = None if not fields else []

            # If a model is defined, extract form fields from it.
            sfields = fields_for_model(opts.model, sfieldnames, sexclude,
                                       opts.widgets, formfield_callback)
            tfields = fields_for_model(mopts.translations_model, tfieldnames,
                                       texclude, opts.widgets,
                                       formfield_callback)

            fields = sfields
            fields.update(tfields)

            # make sure opts.fields doesn't specify an invalid field
            none_model_fields = [k for k, v in fields.iteritems() if not v]
            missing_fields = set(none_model_fields) - \
                             set(declared_fields.keys())
            if missing_fields:
                message = 'Unknown field(s) (%s) specified for %s'
                message = message % (', '.join(missing_fields),
                                     opts.model.__name__)
                raise FieldError(message)
            # Override default model fields with any custom declared ones
            # (plus, include all the other declared fields).
            fields.update(declared_fields)

            if new_class._meta.exclude:
                new_class._meta.exclude = list(new_class._meta.exclude)
            else:
                new_class._meta.exclude = []

            for field in (mopts.translations_accessor, 'master'):
                if not field in new_class._meta.exclude:
                    new_class._meta.exclude.append(field)
        else:
            fields = declared_fields
        new_class.declared_fields = declared_fields
        new_class.base_fields = fields
        # always exclude the FKs
        return new_class
Exemple #12
0
def stream(nead_version, hashed_lines, model_class, display_values, null_value,
           start, end, dict_fields, **kwargs):

    # If kwargs 'start' and 'end' passed in URL validate and assign to dict_timestamps
    dict_timestamps = {}
    if '' not in [start, end]:
        dict_timestamps = get_timestamp_iso_range_day_dict(start, end)

    # Create buffer_ and writer objects
    buffer_ = StringIO()
    writer = csv.writer(buffer_, lineterminator="\n")

    # Check if values passed for 'nead_version' and 'hashed_lines'
    # If True: Write version and hash_lines to buffer_
    if len(nead_version) > 0 and len(hashed_lines) > 0:
        buffer_.writelines(nead_version)
        buffer_.writelines(hashed_lines)
    # Else: Write 'display_values' to buffer_
    else:
        buffer_.writelines(','.join(display_values) + '\n')

    # Generator expressions to write each row in the queryset by calculating each row as needed and not all at once
    # Write values that are null in database as the value assigned to 'null_value'
    # Check if 'dict_fields' passed, if so stream aggregate daily data
    if len(dict_fields) > 0:

        queryset = model_class.objects \
            .values_list('day') \
            .annotate(**dict_fields) \
            .filter(**dict_timestamps) \
            .order_by('timestamp_first') \
            .iterator()

        for row in queryset:
            # Call write_row
            write_row(writer, null_value, row)

            # Yield data (row from database)
            buffer_.seek(0)
            data = buffer_.read()
            buffer_.seek(0)
            buffer_.truncate()
            yield data

    # Elif kwargs 'start' and 'end' passed then apply timestamps filter
    elif len(dict_timestamps) > 0:

        queryset = model_class.objects \
            .values_list(*display_values) \
            .filter(**dict_timestamps) \
            .order_by('timestamp_iso') \
            .iterator()

        for row in queryset:
            # Call write_row
            write_row(writer, null_value, row)

            # Yield data (row from database)
            buffer_.seek(0)
            data = buffer_.read()
            buffer_.seek(0)
            buffer_.truncate()
            yield data

    # Elif retrieve all data currently in database table if 'display_values' passed and 'start' and 'end' are not passed
    elif len(display_values) > 0:

        queryset = model_class.objects \
            .values_list(*display_values) \
            .order_by('timestamp_iso') \
            .iterator()

        for row in queryset:
            # Call write_row
            write_row(writer, null_value, row)

            # Yield data (row from database)
            buffer_.seek(0)
            data = buffer_.read()
            buffer_.seek(0)
            buffer_.truncate()
            yield data

    else:
        raise FieldError(
            "ERROR (stream.py) 'display_values' not passed in API call")
Exemple #13
0
 def _get_natural_language_explantions(self):
     if self.natural_language_explanations.count() < 1:
         raise FieldError("No NL Explanations")
     return self.natural_language_explanations.all()
Exemple #14
0
 def _get_trigger_explanations(self):
     if self.trigger_explanations.count() < 1:
         raise FieldError("No Triggers")
     return self.trigger_explanations.all()
Exemple #15
0
    def get_related_selections(self, select, opts=None, root_alias=None, cur_depth=1,
                               requested=None, restricted=None):
        """
        Fill in the information needed for a select_related query. The current
        depth is measured as the number of connections away from the root model
        (for example, cur_depth=1 means we are looking at models with direct
        connections to the root model).
        """
        def _get_field_choices():
            direct_choices = (f.name for f in opts.fields if f.is_relation)
            reverse_choices = (
                f.field.related_query_name()
                for f in opts.related_objects if f.field.unique
            )
            return chain(direct_choices, reverse_choices)

        related_klass_infos = []
        if not restricted and self.query.max_depth and cur_depth > self.query.max_depth:
            # We've recursed far enough; bail out.
            return related_klass_infos

        if not opts:
            opts = self.query.get_meta()
            root_alias = self.query.get_initial_alias()
        only_load = self.query.get_loaded_field_names()

        # Setup for the case when only particular related fields should be
        # included in the related selection.
        fields_found = set()
        if requested is None:
            if isinstance(self.query.select_related, dict):
                requested = self.query.select_related
                restricted = True
            else:
                restricted = False

        def get_related_klass_infos(klass_info, related_klass_infos):
            klass_info['related_klass_infos'] = related_klass_infos

        for f in opts.fields:
            field_model = f.model._meta.concrete_model
            fields_found.add(f.name)

            if restricted:
                next = requested.get(f.name, {})
                if not f.is_relation:
                    # If a non-related field is used like a relation,
                    # or if a single non-relational field is given.
                    if next or (cur_depth == 1 and f.name in requested):
                        raise FieldError(
                            "Non-relational field given in select_related: '%s'. "
                            "Choices are: %s" % (
                                f.name,
                                ", ".join(_get_field_choices()) or '(none)',
                            )
                        )
            else:
                next = False

            if not select_related_descend(f, restricted, requested,
                                          only_load.get(field_model)):
                continue
            klass_info = {
                'model': f.remote_field.model,
                'field': f,
                'reverse': False,
                'from_parent': False,
            }
            related_klass_infos.append(klass_info)
            select_fields = []
            _, _, _, joins, _ = self.query.setup_joins(
                [f.name], opts, root_alias)
            alias = joins[-1]
            columns = self.get_default_columns(start_alias=alias, opts=f.remote_field.model._meta)
            for col in columns:
                select_fields.append(len(select))
                select.append((col, None))
            klass_info['select_fields'] = select_fields
            next_klass_infos = self.get_related_selections(
                select, f.remote_field.model._meta, alias, cur_depth + 1, next, restricted)
            get_related_klass_infos(klass_info, next_klass_infos)

        if restricted:
            related_fields = [
                (o.field, o.related_model)
                for o in opts.related_objects
                if o.field.unique and not o.many_to_many
            ]
            for f, model in related_fields:
                if not select_related_descend(f, restricted, requested,
                                              only_load.get(model), reverse=True):
                    continue

                related_field_name = f.related_query_name()
                fields_found.add(related_field_name)

                _, _, _, joins, _ = self.query.setup_joins([related_field_name], opts, root_alias)
                alias = joins[-1]
                from_parent = issubclass(model, opts.model)
                klass_info = {
                    'model': model,
                    'field': f,
                    'reverse': True,
                    'from_parent': from_parent,
                }
                related_klass_infos.append(klass_info)
                select_fields = []
                columns = self.get_default_columns(
                    start_alias=alias, opts=model._meta, from_parent=opts.model)
                for col in columns:
                    select_fields.append(len(select))
                    select.append((col, None))
                klass_info['select_fields'] = select_fields
                next = requested.get(f.related_query_name(), {})
                next_klass_infos = self.get_related_selections(
                    select, model._meta, alias, cur_depth + 1,
                    next, restricted)
                get_related_klass_infos(klass_info, next_klass_infos)
            fields_not_found = set(requested.keys()).difference(fields_found)
            if fields_not_found:
                invalid_fields = ("'%s'" % s for s in fields_not_found)
                raise FieldError(
                    'Invalid field name(s) given in select_related: %s. '
                    'Choices are: %s' % (
                        ', '.join(invalid_fields),
                        ', '.join(_get_field_choices()) or '(none)',
                    )
                )
        return related_klass_infos
Exemple #16
0
 def __init__(self):
     super().__init__()
     if self.fields and self.exclude:
         raise FieldError()
     self._header, self._names = self._setup_fields()
Exemple #17
0
def require_postgres(connection):
    engine = connection.settings_dict['ENGINE']
    if 'psycopg2' not in engine and 'postgis' not in engine and 'django_postgrespool' not in engine:
        raise FieldError(
            "Array fields are currently implemented only for PostgreSQL/psycopg2"
        )
Exemple #18
0
    def get(self, request):
        try:

            search = request.GET.get("search")

            article = ArticleSection.objects.all()
            if not search:
                category = request.GET.get("category")
                if not category:
                    raise FieldError("category or search input not valid")
                categoryObject = Topic.objects.get(topic=category)
                if not categoryObject:
                    raise EmptyResultSet

                article = ArticleSection.objects.filter(topic=categoryObject)

                articleSection = []
                for i in article:
                    article = []
                    for j in i.section.all():
                        article.append({
                            "id": j.id,
                            "title": j.title,
                            "content": j.content
                        })
                    articleSection.append({
                        "id": i.id,
                        "title": i.title,
                        "article": article
                    })

                return Response(
                    {
                        "status": status.HTTP_200_OK,
                        "message": "success",
                        "data": {
                            'section': articleSection,
                            'count': len(articleSection),
                        }
                    },
                    status=status.HTTP_200_OK)

            else:
                article = Article.objects.filter(title__icontains=search)
                articles = []
                for i in article:
                    articles.append({
                        'id': i.id,
                        'title': i.title,
                        'content': i.content
                    })

                return Response(
                    {
                        "status": status.HTTP_200_OK,
                        "message": "success",
                        "data": {
                            "articles": articles,
                            'count': len(article)
                        }
                    },
                    status=status.HTTP_200_OK)

        except FieldError as e:
            return FieldErrorHandler(e)

        except EmptyResultSet as e:
            return EmptyResultSetHandler(e)

        except Exception as e:
            return ExceptionHandler(e)
Exemple #19
0
    def _add_select_related(self, language_code):
        fields = self._raw_select_related
        related_queries = []
        language_filters = []
        force_unique_fields = []
        if not self._skip_master_select and getattr(self, '_fields',
                                                    None) is None:
            related_queries.append('master')

        for query_key in fields:
            newbits = []
            for term in query_terms(self.shared_model, query_key):

                # Translate term
                if term.depth == 0 and not term.translated:
                    # on initial depth we must key to shared model
                    newbits.append('master__%s' % term.term)
                elif term.depth > 0 and term.translated:
                    # on deeper levels we must key to translations model
                    # this will work because translations will be seen as _unique
                    # at query time
                    newbits.append(
                        '%s__%s' %
                        (term.model._meta.translations_accessor, term.term))
                else:
                    newbits.append(term.term)

                # Some helpful messages for common mistakes
                if term.many:
                    raise FieldError(
                        'Cannot select_related: %s can be multiple objects. '
                        'Use prefetch_related instead.' % query_key)
                if term.target is None:
                    raise FieldError(
                        'Cannot select_related: %s is a regular field' %
                        query_key)
                if hasattr(term.field.rel, 'through'):
                    raise FieldError(
                        'Cannot select_related: %s can be multiple objects. '
                        'Use prefetch_related instead.' % query_key)

                # If target is a translated model, select its translations
                target_translations = getattr(term.target._meta,
                                              'translations_accessor', None)
                if target_translations is not None:
                    # Add the model
                    target_query = '__'.join(newbits)
                    related_queries.append('%s__%s' %
                                           (target_query, target_translations))

                    # Add a language filter for the translation
                    language_filters.append('%s__%s__language_code' % (
                        target_query,
                        target_translations,
                    ))

                    # Remember to mark the field unique so JOIN is generated
                    # and row decoder gets cached items
                    if django.VERSION >= (1, 9):
                        target_transfield = getattr(term.target,
                                                    target_translations).field
                    else:
                        target_transfield = getattr(
                            term.target, target_translations).related.field
                    force_unique_fields.append(target_transfield)

            related_queries.append('__'.join(newbits))

        # Apply results to query
        self.query.add_select_related(related_queries)
        for language_filter in language_filters:
            self.query.add_q(
                Q(**{language_filter: language_code})
                | Q(**{language_filter: None}))

        self._forced_unique_fields = force_unique_fields
Exemple #20
0
    def _traverse_tree(self, q_object, negate=False):
        """
        Helper function that traverse a Q tree object,
        replacing filter expression involving the primary key
        and other fields not present on the Translation object
        """

        # List of model fields directly accessible from Translation objects
        direct_fields = self.model.Translation.fields + self.model.Translation.excludes + [
            'lang', 'source'
        ]
        # Let's add the sacred trinity; we don't want to mess with those guys
        direct_fields += ['published', 'release_date', 'embargo_date']

        new_children = []

        # Iterate over children and generate a new list of children
        # - if a child contains a filter expression with the primary key
        #   it's replaced.
        for child in q_object.children:
            # A tree node is a Q object - so traverse it with a recursive call
            if isinstance(child, Q):
                new_children.append(self._traverse_tree(child, negate))
            # A leaf node is tuple: (filter expression, value)
            else:
                arg, value = child
                # Split filter expression
                parts = arg.split(LOOKUP_SEP)
                if not parts:
                    raise FieldError("Cannot parse keyword query %r" % arg)

                # Check if we're filter expression involves the primary key
                field = parts.pop(0)

                # If it's a negated expression we bypass the inclusion of source__pk
                if not negate:

                    # If the query concerns the private key we also look in the
                    # source, to match e.g.: 'ann1401' and 'ann1401de'
                    if field == 'pk' or field == self.model._meta.pk.name:
                        new_children.append(
                            Q(**{arg: value}) | Q(**{
                                LOOKUP_SEP.join(['source', 'pk'] + parts):
                                value
                            }))
                        continue

                    if field not in direct_fields:
                        # The field is not directly stored in the model (i.e.: it's a foreign
                        # key or many to many), so we check if the relation is a "Translation" one

                        field_type = ''
                        # Get FieldType name
                        try:
                            field_type = self.model._meta.get_field(
                                field).get_internal_type()
                        except AttributeError:
                            if hasattr(self.model, field + '_set'):
                                field_type = getattr(
                                    self.model, field +
                                    '_set').related.field.get_internal_type()

                        if field_type.startswith('Translation'):
                            # Field is translated and not directly accessible so
                            # we access the one from the source instead
                            # Note: this (can) create massive SQL JOINs (at least as of
                            # Django 1.5). Ideally this could be replaced by something
                            # smarter, for example by using directly the source_pk in
                            # the ForeignKey to remove an extra JOIN
                            #  new_children.append( Q( **{ LOOKUP_SEP.join( ['source', field] + parts ): value } ) )
                            new_children.append(
                                Q(
                                    **{arg: value
                                       }) | Q(
                                           **{
                                               LOOKUP_SEP.join([
                                                   'source', field
                                               ] + parts):
                                               value
                                           }))
                            continue

                new_children.append(child)

        q_object.children = new_children
        return q_object
Exemple #21
0
 def has_changed(self, field):
     """Returns ``True`` if field has changed from currently saved value"""
     if field in self.fields:
         return self.previous(field) != self.get_field_value(field)
     else:
         raise FieldError('field "%s" not tracked' % field)
Exemple #22
0
def patched_new(cls, name, bases, attrs):
    "Patched version of __new__"

    super_new = super(ModelBase, cls).__new__

    # Also ensure initialization is only performed for subclasses of Model
    # (excluding Model class itself).
    parents = [b for b in bases if isinstance(b, ModelBase)]
    if not parents:
        return super_new(cls, name, bases, attrs)

    # Create the class.
    module = attrs.pop('__module__')
    new_class = super_new(cls, name, bases, {'__module__': module})
    attr_meta = attrs.pop('Meta', None)
    abstract = getattr(attr_meta, 'abstract', False)
    if not attr_meta:
        meta = getattr(new_class, 'Meta', None)
    else:
        meta = attr_meta
    base_meta = getattr(new_class, '_meta', None)

    # Look for an application configuration to attach the model to.
    app_config = apps.get_containing_app_config(module)

    if getattr(meta, 'app_label', None) is None:

        if app_config is None:
            # If the model is imported before the configuration for its
            # application is created (#21719), or isn't in an installed
            # application (#21680), use the legacy logic to figure out the
            # app_label by looking one level up from the package or module
            # named 'models'. If no such package or module exists, fall
            # back to looking one level up from the module this model is
            # defined in.

            # For 'django.contrib.sites.models', this would be 'sites'.
            # For 'geo.models.places' this would be 'geo'.

            msg = ("Model class %s.%s doesn't declare an explicit app_label "
                   "and either isn't in an application in INSTALLED_APPS or "
                   "else was imported before its application was loaded. " %
                   (module, name))
            if abstract:
                msg += "Its app_label will be set to None in Django 1.9."
            else:
                msg += "This will no longer be supported in Django 1.9."
            warnings.warn(msg, RemovedInDjango19Warning, stacklevel=2)

            model_module = sys.modules[new_class.__module__]
            package_components = model_module.__name__.split('.')
            package_components.reverse(
            )  # find the last occurrence of 'models'
            try:
                app_label_index = package_components.index(
                    MODELS_MODULE_NAME) + 1
            except ValueError:
                app_label_index = 1
            kwargs = {"app_label": package_components[app_label_index]}

        else:
            kwargs = {"app_label": app_config.label}

    else:
        kwargs = {}

    new_class.add_to_class('_meta', Options(meta, **kwargs))
    if not abstract:
        new_class.add_to_class(
            'DoesNotExist',
            subclass_exception(
                str('DoesNotExist'),
                tuple(x.DoesNotExist for x in parents
                      if hasattr(x, '_meta') and not x._meta.abstract)
                or (ObjectDoesNotExist, ),
                module,
                attached_to=new_class))
        new_class.add_to_class(
            'MultipleObjectsReturned',
            subclass_exception(
                str('MultipleObjectsReturned'),
                tuple(x.MultipleObjectsReturned for x in parents
                      if hasattr(x, '_meta') and not x._meta.abstract)
                or (MultipleObjectsReturned, ),
                module,
                attached_to=new_class))
        if base_meta and not base_meta.abstract:
            # Non-abstract child classes inherit some attributes from their
            # non-abstract parent (unless an ABC comes before it in the
            # method resolution order).
            if not hasattr(meta, 'ordering'):
                new_class._meta.ordering = base_meta.ordering
            if not hasattr(meta, 'get_latest_by'):
                new_class._meta.get_latest_by = base_meta.get_latest_by

    is_proxy = new_class._meta.proxy

    # If the model is a proxy, ensure that the base class
    # hasn't been swapped out.
    if is_proxy and base_meta and base_meta.swapped:
        raise TypeError("%s cannot proxy the swapped model '%s'." %
                        (name, base_meta.swapped))

    if getattr(new_class, '_default_manager', None):
        if not is_proxy:
            # Multi-table inheritance doesn't inherit default manager from
            # parents.
            new_class._default_manager = None
            new_class._base_manager = None
        else:
            # Proxy classes do inherit parent's default manager, if none is
            # set explicitly.
            new_class._default_manager = new_class._default_manager._copy_to_model(
                new_class)
            new_class._base_manager = new_class._base_manager._copy_to_model(
                new_class)

    # Add all attributes to the class.
    for obj_name, obj in attrs.items():
        new_class.add_to_class(obj_name, obj)

    # All the fields of any type declared on this model
    new_fields = (new_class._meta.local_fields +
                  new_class._meta.local_many_to_many +
                  new_class._meta.virtual_fields)
    field_names = set(f.name for f in new_fields)

    # Basic setup for proxy models.
    if is_proxy:
        base = None
        for parent in [kls for kls in parents if hasattr(kls, '_meta')]:
            if parent._meta.abstract:
                if parent._meta.fields:
                    raise TypeError(
                        "Abstract base class containing model fields not permitted for proxy model '%s'."
                        % name)
                else:
                    continue
            #if base is not None:                              # patch
            while parent._meta.proxy:  # patch
                parent = parent._meta.proxy_for_model  # patch
            if base is not None and base is not parent:  # patch
                raise TypeError(
                    "Proxy model '%s' has more than one non-abstract model base class."
                    % name)
            else:
                base = parent
        if base is None:
            raise TypeError(
                "Proxy model '%s' has no non-abstract model base class." %
                name)
        new_class._meta.setup_proxy(base)
        new_class._meta.concrete_model = base._meta.concrete_model
    else:
        new_class._meta.concrete_model = new_class

    # Collect the parent links for multi-table inheritance.
    parent_links = {}
    for base in reversed([new_class] + parents):
        # Conceptually equivalent to `if base is Model`.
        if not hasattr(base, '_meta'):
            continue
        # Skip concrete parent classes.
        if base != new_class and not base._meta.abstract:
            continue
        # Locate OneToOneField instances.
        for field in base._meta.local_fields:
            if isinstance(field, OneToOneField):
                parent_links[field.rel.to] = field

    # Do the appropriate setup for any model parents.
    for base in parents:
        original_base = base
        if not hasattr(base, '_meta'):
            # Things without _meta aren't functional models, so they're
            # uninteresting parents.
            continue

        parent_fields = base._meta.local_fields + base._meta.local_many_to_many
        # Check for clashes between locally declared fields and those
        # on the base classes (we cannot handle shadowed fields at the
        # moment).
        for field in parent_fields:
            if field.name in field_names:
                raise FieldError('Local field %r in class %r clashes '
                                 'with field of similar name from '
                                 'base class %r' %
                                 (field.name, name, base.__name__))
        if not base._meta.abstract:
            # Concrete classes...
            base = base._meta.concrete_model
            if base in parent_links:
                field = parent_links[base]
            elif not is_proxy:
                attr_name = '%s_ptr' % base._meta.model_name
                field = OneToOneField(base,
                                      name=attr_name,
                                      auto_created=True,
                                      parent_link=True)
                # Only add the ptr field if it's not already present;
                # e.g. migrations will already have it specified
                if not hasattr(new_class, attr_name):
                    new_class.add_to_class(attr_name, field)
            else:
                field = None
            new_class._meta.parents[base] = field
        else:
            # .. and abstract ones.
            for field in parent_fields:
                new_class.add_to_class(field.name, copy.deepcopy(field))

            # Pass any non-abstract parent classes onto child.
            new_class._meta.parents.update(base._meta.parents)

        # Inherit managers from the abstract base classes.
        new_class.copy_managers(base._meta.abstract_managers)

        # Proxy models inherit the non-abstract managers from their base,
        # unless they have redefined any of them.
        if is_proxy:
            new_class.copy_managers(original_base._meta.concrete_managers)

        # Inherit virtual fields (like GenericForeignKey) from the parent
        # class
        for field in base._meta.virtual_fields:
            if base._meta.abstract and field.name in field_names:
                raise FieldError('Local field %r in class %r clashes '
                                 'with field of similar name from '
                                 'abstract base class %r' %
                                 (field.name, name, base.__name__))
            new_class.add_to_class(field.name, copy.deepcopy(field))

    if abstract:
        # Abstract base models can't be instantiated and don't appear in
        # the list of models for an app. We do the final setup for them a
        # little differently from normal models.
        attr_meta.abstract = False
        new_class.Meta = attr_meta
        return new_class

    new_class._prepare()
    new_class._meta.apps.register_model(new_class._meta.app_label, new_class)

    return new_class
Exemple #23
0
def create_page(title,
                template,
                language,
                menu_title=None,
                slug=None,
                apphook=None,
                apphook_namespace=None,
                redirect=None,
                meta_description=None,
                created_by='python-api',
                parent=None,
                publication_date=None,
                publication_end_date=None,
                in_navigation=False,
                soft_root=False,
                reverse_id=None,
                navigation_extenders=None,
                published=False,
                site=None,
                login_required=False,
                limit_visibility_in_menu=constants.VISIBILITY_ALL,
                position="last-child",
                overwrite_url=None,
                xframe_options=Page.X_FRAME_OPTIONS_INHERIT,
                with_revision=False):
    """
    Create a CMS Page and it's title for the given language

    See docs/extending_cms/api_reference.rst for more info
    """
    if with_revision:
        # fail fast if revision is requested
        # but not enabled on the project.
        _verify_revision_support()

    # ugly permissions hack
    if created_by and isinstance(created_by, get_user_model()):
        _thread_locals.user = created_by

        created_by = getattr(created_by, get_user_model().USERNAME_FIELD)
    else:
        _thread_locals.user = None

    # validate template
    if not template == TEMPLATE_INHERITANCE_MAGIC:
        assert template in [tpl[0] for tpl in get_cms_setting('TEMPLATES')]
        get_template(template)

    # validate site
    if not site:
        site = Site.objects.get_current()
    else:
        assert isinstance(site, Site)

    # validate language:
    assert language in get_language_list(site), get_cms_setting(
        'LANGUAGES').get(site.pk)

    # set default slug:
    if not slug:
        slug = generate_valid_slug(title, parent, language)

    # validate parent
    if parent:
        assert isinstance(parent, Page)
        parent = Page.objects.get(pk=parent.pk)

    # validate publication date
    if publication_date:
        assert isinstance(publication_date, datetime.date)

    # validate publication end date
    if publication_end_date:
        assert isinstance(publication_end_date, datetime.date)

    if navigation_extenders:
        raw_menus = menu_pool.get_menus_by_attribute("cms_enabled", True)
        menus = [menu[0] for menu in raw_menus]
        assert navigation_extenders in menus

    # validate menu visibility
    accepted_limitations = (constants.VISIBILITY_ALL,
                            constants.VISIBILITY_USERS,
                            constants.VISIBILITY_ANONYMOUS)
    assert limit_visibility_in_menu in accepted_limitations

    # validate position
    assert position in ('last-child', 'first-child', 'left', 'right')
    if parent:
        if position in ('last-child', 'first-child'):
            parent_id = parent.pk
        else:
            parent_id = parent.parent_id
    else:
        parent_id = None
    # validate and normalize apphook
    if apphook:
        application_urls = _verify_apphook(apphook, apphook_namespace)
    else:
        application_urls = None

    if reverse_id:
        if Page.objects.drafts().filter(reverse_id=reverse_id,
                                        site=site).count():
            raise FieldError('A page with the reverse_id="%s" already exist.' %
                             reverse_id)

    page = Page(
        created_by=created_by,
        changed_by=created_by,
        parent_id=parent_id,
        publication_date=publication_date,
        publication_end_date=publication_end_date,
        in_navigation=in_navigation,
        soft_root=soft_root,
        reverse_id=reverse_id,
        navigation_extenders=navigation_extenders,
        template=template,
        application_urls=application_urls,
        application_namespace=apphook_namespace,
        site=site,
        login_required=login_required,
        limit_visibility_in_menu=limit_visibility_in_menu,
        xframe_options=xframe_options,
    )
    page = page.add_root(instance=page)

    if parent:
        page = page.move(target=parent, pos=position)

    create_title(
        language=language,
        title=title,
        menu_title=menu_title,
        slug=slug,
        redirect=redirect,
        meta_description=meta_description,
        page=page,
        overwrite_url=overwrite_url,
    )

    if published:
        page.publish(language)

    if with_revision:
        from cms.constants import REVISION_INITIAL_COMMENT

        _create_revision(
            obj=page,
            user=_thread_locals.user,
            message=REVISION_INITIAL_COMMENT,
        )

    del _thread_locals.user
    return page.reload()
Exemple #24
0
 def template_matches(self):
     ct = self.template_comparison
     if ct is None:
         raise FieldError("Template matches requested before matching a submission")
     return json.loads(ct.matches_json)
Exemple #25
0
 def reactivate_device(self, user):
     if Device.objects.filter(device_id=self.device_id, is_active=True):
         raise FieldError('This device is currently active.', self)
     self.user = user
     self.is_active = True
     self.save()
Exemple #26
0
 def output_field(self):
     """Return the output type of this expressions."""
     if self._output_field_or_none is None:
         raise FieldError("Cannot resolve expression type, unknown output_field")
     return self._output_field_or_none
Exemple #27
0
 def get_field(self, name):
     raise FieldError(
         "Cannot resolve keyword %r into field. Join on '%s'"
         " not permitted." % (name, self.field_name)
     )
Exemple #28
0
    def __new__(cls, name, bases, attrs):
        # Force presence of meta class, we need it
        meta = attrs.get('Meta')
        if meta is None:
            # if a base class has a Meta, inherit it
            base_meta = next(((base.Meta,) for base in bases if hasattr(base, 'Meta')), ())
            meta = attrs['Meta'] = type('Meta', base_meta + (object,), {})

        model = getattr(meta, 'model', None)
        fields = getattr(meta, 'fields', None)
        if fields == ALL_FIELDS:
            fields = None

        # Force exclusion of language_code as we use cleaned_data['language_code']
        exclude = set(getattr(meta, 'exclude', ()))
        if fields is not None and 'language_code' in fields:
            raise FieldError('Field \'language_code\' is invalid.')

        # If a model is provided, handle translatable fields
        if model:
            if not issubclass(model, TranslatableModel):
                raise TypeError('TranslatableModelForm only works with TranslatableModel'
                                ' subclasses, which %s is not.' % model.__name__)

            # Additional exclusions
            exclude.add(model._meta.translations_accessor)
            if fields is not None and model._meta.translations_accessor in fields:
                raise FieldError('Field \'%s\' is invalid', model._meta.translations_accessor)

            # Get translatable fields
            tfields = fields_for_model(
                model._meta.translations_model,
                fields=fields,
                exclude=exclude | veto_fields,
                widgets=getattr(meta, 'widgets', None),
                formfield_callback=attrs.get('formfield_callback')
            )

            # Drop translatable fields from Meta.fields
            if fields is not None:
                meta.fields = [field for field in fields if tfields.get(field) is None]

        meta.exclude = list(exclude)

        # Create the form class
        new_class = super(TranslatableModelFormMetaclass, cls).__new__(cls, name, bases, attrs)

        # Add translated fields into the form's base fields
        if model:
            if fields is None:
                # loop, as Django's variant of OrderedDict cannot consume generators
                for name, field in tfields.items():
                    if field is not None:
                        new_class.base_fields[name] = field
            else:
                # rebuild the fields to respect Meta.fields ordering
                new_class.base_fields = OrderedDict(
                    item for item in (
                        (name, new_class.base_fields.get(name, tfields.get(name)))
                        for name in fields
                    )
                    if item[1] is not None
                )
                # restore hijacked Meta.fields
                new_class._meta.fields = meta.fields = fields
        return new_class
Exemple #29
0
def create_page(title,
                template,
                language,
                menu_title=None,
                slug=None,
                apphook=None,
                apphook_namespace=None,
                redirect=None,
                meta_description=None,
                created_by='python-api',
                parent=None,
                publication_date=None,
                publication_end_date=None,
                in_navigation=False,
                soft_root=False,
                reverse_id=None,
                navigation_extenders=None,
                published=False,
                site=None,
                login_required=False,
                limit_visibility_in_menu=constants.VISIBILITY_ALL,
                position="last-child",
                overwrite_url=None,
                xframe_options=Page.X_FRAME_OPTIONS_INHERIT,
                page_title=None,
                is_home=False):
    """
    Create a CMS Page and it's title for the given language

    See docs/extending_cms/api_reference.rst for more info
    """
    # validate template
    if not template == TEMPLATE_INHERITANCE_MAGIC:
        assert template in [tpl[0] for tpl in get_cms_setting('TEMPLATES')]
        get_template(template)

    # validate site
    if not site:
        site = get_current_site()
    else:
        assert isinstance(site, Site)

    # validate language:
    assert language in get_language_list(site), get_cms_setting(
        'LANGUAGES').get(site.pk)

    # validate parent
    if parent:
        assert isinstance(parent, Page)
        assert parent.publisher_is_draft

    # validate publication date
    if publication_date:
        assert isinstance(publication_date, datetime.date)

    # validate publication end date
    if publication_end_date:
        assert isinstance(publication_end_date, datetime.date)

    if navigation_extenders:
        raw_menus = menu_pool.get_menus_by_attribute("cms_enabled", True)
        menus = [menu[0] for menu in raw_menus]
        assert navigation_extenders in menus

    # validate menu visibility
    accepted_limitations = (constants.VISIBILITY_ALL,
                            constants.VISIBILITY_USERS,
                            constants.VISIBILITY_ANONYMOUS)
    assert limit_visibility_in_menu in accepted_limitations

    # validate position
    assert position in ('last-child', 'first-child', 'left', 'right')
    target_node = parent.node if parent else None

    # validate and normalize apphook
    if apphook:
        application_urls = _verify_apphook(apphook, apphook_namespace)
    else:
        application_urls = None

    # ugly permissions hack
    if created_by and isinstance(created_by, get_user_model()):
        _thread_locals.user = created_by
        created_by = getattr(created_by, get_user_model().USERNAME_FIELD)
    else:
        _thread_locals.user = None

    if reverse_id:
        if Page.objects.drafts().filter(reverse_id=reverse_id,
                                        node__site=site).exists():
            raise FieldError('A page with the reverse_id="%s" already exist.' %
                             reverse_id)

    page = Page(created_by=created_by,
                changed_by=created_by,
                publication_date=publication_date,
                publication_end_date=publication_end_date,
                in_navigation=in_navigation,
                soft_root=soft_root,
                reverse_id=reverse_id,
                navigation_extenders=navigation_extenders,
                template=template,
                application_urls=application_urls,
                application_namespace=apphook_namespace,
                login_required=login_required,
                limit_visibility_in_menu=limit_visibility_in_menu,
                xframe_options=xframe_options,
                is_home=is_home)
    page.set_tree_node(site=site, target=target_node, position=position)
    page.save()
    page.rescan_placeholders()

    create_title(
        language=language,
        title=title,
        page_title=page_title,
        menu_title=menu_title,
        slug=slug,
        redirect=redirect,
        meta_description=meta_description,
        page=page,
        overwrite_url=overwrite_url,
    )

    if published:
        page.publish(language)

    if parent and position in ('last-child', 'first-child'):
        parent._clear_node_cache()

    del _thread_locals.user
    return page
Exemple #30
0
        self.filter = self.filter and exprs.pop()
        return super().set_source_expressions(exprs)

    def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False):
        # Aggregates are not allowed in UPDATE queries, so ignore for_save
        c = super().resolve_expression(query, allow_joins, reuse, summarize)
        c.filter = c.filter and c.filter.resolve_expression(query, allow_joins, reuse, summarize)
        if not summarize:
            # Call Aggregate.get_source_expressions() to avoid
            # returning self.filter and including that in this loop.
            expressions = super(Aggregate, c).get_source_expressions()
            for index, expr in enumerate(expressions):
                if expr.contains_aggregate:
                    before_resolved = self.get_source_expressions()[index]
                    name = before_resolved.name if hasattr(before_resolved, 'name') else repr(before_resolved)
                    raise FieldError("Cannot compute %s('%s'): '%s' is an aggregate" % (c.name, name, name))
        return c

    @property
    def default_alias(self):
        expressions = self.get_source_expressions()
        if len(expressions) == 1 and hasattr(expressions[0], 'name'):
            return '%s__%s' % (expressions[0].name, self.name.lower())
        raise TypeError("Complex expressions require an alias")

    def get_group_by_cols(self, alias=None):
        return []

    def as_sql(self, compiler, connection, **extra_context):
        extra_context['distinct'] = 'DISTINCT ' if self.distinct else ''
        if self.filter: