Example #1
0
def check_for_chooser(model, field):
    if isinstance(field, fields.DummyField):
        return
    methname = field.name + "_choices"
    m = get_class_attr(model, methname)
    if m is not None:
        ch = Chooser(model, field, m)
        setattr(field, '_lino_chooser', ch)
Example #2
0
    def get_data_elem(cls, name):
        """Return the named data element. This can be a database field, a
        :class:`lino.core.fields.RemoteField`, a
        :class:`lino.core.fields.VirtualField` or a Django-style
        virtual field (GenericForeignKey).

        """
        #~ logger.info("20120202 get_data_elem %r,%r",model,name)
        if not name.startswith('__'):
            parts = name.split('__')
            if len(parts) > 1:
                # It's going to be a RemoteField
                # logger.warning("20151203 RemoteField %s in %s", name, cls)

                from lino.core import store

                model = cls
                field_chain = []
                for n in parts:
                    if model is None:
                        raise Exception(
                            "Invalid remote field {0} for {1}".format(name, cls))

                    if isinstance(model, basestring):
                        model = resolve_model(model)
                        # logger.warning("20151203 %s", model)
                        # Django 1.9 no longer resolves the
                        # rel.model of ForeignKeys on abstract
                        # models.

                    # ~ 20130508 model.get_default_table().get_handle() # make sure that all atomizers of those fields get created.
                    fld = model.get_data_elem(n)
                    if fld is None:
                        # raise Exception("Part %s of %s got None" % (n,model))
                        raise Exception(
                            "Invalid RemoteField %s.%s (no field %s in %s)" %
                            (full_model_name(model), name, n, full_model_name(model)))
                    # make sure that the atomizer gets created.
                    store.get_atomizer(model, fld, fld.name)
                    field_chain.append(fld)
                    if getattr(fld, 'rel', None):
                        if AFTER18:
                            model = fld.rel.model
                        else:
                            model = fld.rel.to
                    else:
                        model = None

                def func(obj, ar=None):
                    try:
                        for fld in field_chain:
                            if obj is None:
                                return obj
                            obj = fld._lino_atomizer.full_value_from_object(
                                obj, ar)
                        return obj
                    except Exception as e:
                        raise Exception(
                            "Error while computing %s: %s" % (name, e))
                        # ~ if False: # only for debugging
                        if True:  # see 20130802
                            logger.exception(e)
                            return str(e)
                        return None
                return fields.RemoteField(func, name, fld)

        try:
            return cls._meta.get_field(name)
        except models.FieldDoesNotExist:
            pass

        v = get_class_attr(cls, name)
        if v is not None:
            return v

        for vf in cls._meta.virtual_fields:
            if vf.name == name:
                return vf
Example #3
0
    def get_data_elem(cls, name):
        """Return the named data element. This can be a database field, a
        :class:`lino.core.fields.RemoteField`, a
        :class:`lino.core.fields.VirtualField` or a Django-style
        virtual field (GenericForeignKey).

        """
        #~ logger.info("20120202 get_data_elem %r,%r",model,name)
        if not name.startswith('__'):
            parts = name.split('__')
            if len(parts) > 1:
                # It's going to be a RemoteField
                # logger.warning("20151203 RemoteField %s in %s", name, cls)

                from lino.core import store

                model = cls
                field_chain = []
                for n in parts:
                    if model is None:
                        raise Exception(
                            "Invalid remote field {0} for {1}".format(name, cls))

                    if isinstance(model, six.string_types):
                        model = resolve_model(model)
                        # logger.warning("20151203 %s", model)
                        # Django 1.9 no longer resolves the
                        # rel.model of ForeignKeys on abstract
                        # models.

                    # ~ 20130508 model.get_default_table().get_handle() # make sure that all atomizers of those fields get created.
                    fld = model.get_data_elem(n)
                    if fld is None:
                        # raise Exception("Part %s of %s got None" % (n,model))
                        raise Exception(
                            "Invalid RemoteField %s.%s (no field %s in %s)" %
                            (full_model_name(model), name, n, full_model_name(model)))
                    # make sure that the atomizer gets created.
                    store.get_atomizer(model, fld, fld.name)
                    field_chain.append(fld)
                    if getattr(fld, 'rel', None):
                        if AFTER18:
                            model = fld.rel.model
                        else:
                            model = fld.rel.to
                    else:
                        model = None

                def func(obj, ar=None):
                    try:
                        for fld in field_chain:
                            if obj is None:
                                return obj
                            obj = fld._lino_atomizer.full_value_from_object(
                                obj, ar)
                        return obj
                    except Exception as e:
                        raise Exception(
                            "Error while computing %s: %s" % (name, e))
                        # ~ if False: # only for debugging
                        if True:  # see 20130802
                            logger.exception(e)
                            return str(e)
                        return None
                return fields.RemoteField(func, name, fld)

        try:
            return cls._meta.get_field(name)
        except models.FieldDoesNotExist:
            pass

        v = get_class_attr(cls, name)
        if v is not None:
            return v

        for vf in cls._meta.virtual_fields:
            if vf.name == name:
                return vf
Example #4
0
    def get_data_elem(cls, name):
        """Return the named data element. This can be a database field, a
        :class:`lino.core.fields.RemoteField`, a
        :class:`lino.core.fields.VirtualField` or a Django-style
        virtual field (GenericForeignKey).

        """
        #~ logger.info("20120202 get_data_elem %r,%r",model,name)
        if not name.startswith('__'):
            parts = name.split('__')
            if len(parts) > 1:
                # It's going to be a RemoteField
                # logger.warning("20151203 RemoteField %s in %s", name, cls)

                from lino.core import store

                model = cls
                field_chain = []
                editable = False
                for n in parts:
                    if model is None:
                        raise Exception(
                            "Invalid remote field {0} for {1}".format(
                                name, cls))

                    if isinstance(model, six.string_types):
                        # Django 1.9 no longer resolves the
                        # rel.model of ForeignKeys on abstract
                        # models, so we do it here.
                        model = resolve_model(model)
                        # logger.warning("20151203 %s", model)

                    fld = model.get_data_elem(n)
                    if fld is None:
                        raise Exception(
                            "Invalid RemoteField %s.%s (no field %s in %s)" %
                            (full_model_name(model), name, n,
                             full_model_name(model)))
                    # make sure that the atomizer gets created.
                    store.get_atomizer(model, fld, fld.name)
                    field_chain.append(fld)
                    if isinstance(fld, models.OneToOneRel):
                        editable = True
                    if getattr(fld, 'remote_field', None):
                        model = fld.remote_field.model
                    elif getattr(fld, 'rel', None):
                        raise Exception("20180712")
                        model = fld.rel.model
                    else:
                        model = None

                def getter(obj, ar=None):
                    try:
                        for fld in field_chain:
                            if obj is None:
                                return None
                            obj = fld._lino_atomizer.full_value_from_object(
                                obj, ar)
                        return obj
                    except Exception as e:
                        # raise
                        msg = "Error while computing {}: {} ({} in {})"
                        raise Exception(msg.format(name, e, fld, field_chain))
                        # ~ if False: # only for debugging
                        if True:  # see 20130802
                            logger.exception(e)
                            return str(e)
                        return None

                if not editable:
                    return fields.RemoteField(getter, name, fld)

                def setter(obj, value):
                    # logger.info("20180712 %s setter() %s", name, value)
                    # all intermediate fields are OneToOneRel
                    target = obj
                    try:
                        for fld in field_chain:
                            # print("20180712a %s" % fld)
                            if isinstance(fld, models.OneToOneRel):
                                reltarget = getattr(target, fld.name, None)
                                if reltarget is None:
                                    rkw = {fld.field.name: target}
                                    # print(
                                    #     "20180712 create {}({})".format(
                                    #         fld.related_model, rkw))
                                    reltarget = fld.related_model(**rkw)
                                    reltarget.full_clean()
                                    reltarget.save()

                                setattr(target, fld.name, reltarget)
                                target.full_clean()
                                target.save()
                                # print("20180712b {}.{} = {}".format(
                                #     target, fld.name, reltarget))
                                target = reltarget
                            else:
                                setattr(target, fld.name, value)
                                target.full_clean()
                                target.save()
                                # print(
                                #     "20180712c setattr({},{},{}".format(
                                #         target, fld.name, value))
                                return True
                    except Exception as e:
                        raise Exception("Error while setting %s: %s" %
                                        (name, e))
                        # ~ if False: # only for debugging
                        if True:  # see 20130802
                            logger.exception(e)
                            return str(e)
                        return False

                return fields.RemoteField(getter, name, fld, setter)

        try:
            return cls._meta.get_field(name)
        except models.FieldDoesNotExist:
            pass

        v = get_class_attr(cls, name)
        if v is not None:
            return v

        for vf in cls._meta.private_fields:
            if vf.name == name:
                return vf
Example #5
0
File: model.py Project: cuchac/lino
        try:
            return model._meta.get_field(name)
        except models.FieldDoesNotExist, e:
            pass

        #~ s = name.split('.')
        #~ if len(s) == 1:
            #~ mod = import_module(model.__module__)
            #~ rpt = getattr(mod,name,None)
        #~ elif len(s) == 2:
            #~ mod = getattr(settings.SITE.modules,s[0])
            #~ rpt = getattr(mod,s[1],None)
        #~ else:
            #~ raise Exception("Invalid data element name %r" % name)

        v = get_class_attr(model, name)
        if v is not None:
            return v

        for vf in model._meta.virtual_fields:
            if vf.name == name:
                return vf

    def get_choices_text(self, request, actor, field):
        """
        Return the text to be displayed when an instance of this model 
        is being used as a choice in a combobox (i.e. by ForeignKey fields 
        pointing to this model).
        `request` is the web request,
        `actor` is the requesting actor.
        Default is to simply return `unicode(self)`.