Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More

lino.core.inject

Functions

check_pending_injects(sender[, models_list])

do_when_prepared(todo, *model_specs)

Execute the specified function todo on all specified models as soon as they are prepared.

fix_field_cache(model)

Remove duplicate entries in the field cache of the specified model in order to fix Django issue #10808

fmt(func_caller)

inject_action(model_spec, **actions)

Add the specified action(s) to the specified model.

inject_field(model_spec, name, field[, doc, ...])

Add the given field to the given model.

inject_quick_add_buttons(model, name, target)

Injects a virtual display field name into the specified model.

on_class_prepared(sender, **kw)

This is Lino's general class_prepared handler.

update_field(model_spec, name, **kw)

Update some attribute of the specified existing field. For example Human defines a field first_name, which may not be blank. If you inherit from this mixin but want first_name to be optional::.

update_model(model_spec, **actions)

Replace the specified attributes in the specified model.

when_prepared(*model_specs)

Decorator to declare a function which will automatically run when the specified models has been prepared.

lino.core.inject.fix_field_cache(model)

Remove duplicate entries in the field cache of the specified model in order to fix Django issue #10808

lino.core.inject.on_class_prepared(sender, **kw)

This is Lino’s general class_prepared handler. It does two things:

  • Run pending calls to inject_field() and update_field().

  • Apply a workaround for Django’s ticket 10808. In a diamond inheritance pattern, _meta._field_cache contains certain fields twice. So we remove these duplicate fields from _meta._field_cache. (A better solution would be of course to not collect them.)

lino.core.inject.do_when_prepared(todo, *model_specs)

Execute the specified function todo on all specified models as soon as they are prepared. If a specified model hasn’t yet been prepared, add the call to a queue and execute it later.

If a model_spec is not a string, the function todo is called immediately.

lino.core.inject.when_prepared(*model_specs)

Decorator to declare a function which will automatically run when the specified models has been prepared. If the model has already been prepared, the function is executed immediately.

lino.core.inject.inject_action(model_spec, **actions)

Add the specified action(s) to the specified model.

This can also be used to inject any other class attribute on a model, e.g. choosers.

lino.core.inject.update_model(model_spec, **actions)

Replace the specified attributes in the specified model.

lino.core.inject.inject_field(model_spec, name, field, doc=None, active=False, **widget_options)

Add the given field to the given model.

The following code:

class Foo(dd.Model):
   field1 = dd.ForeignKey(...)

dd.inject_field(Foo, 'field2', models.CharField(max_length=20))

is functionally equivalent to this code:

class Foo(dd.Model):
   field1 = dd.ForeignKey(Bar)
   field2 = models.CharField(max_length=20)

Because inject_field is usually called at the global level of models modules, it cannot know whether the given model_spec has already been imported (and its class prepared) or not. That’s why it uses Django’s class_prepared signal to maintain its own list of models.

Note that inject_field() causes problems when the modified model has subclasses and is not abstract (i.e., is an MTI parent). Subclasses will have only some part of the injected field’s definition.

Optional keyword arguments:

  • doc : a docstring for the field

  • active : whether to call add_active_field for the injected field.

  • any other keyword arguments are forwarded to the model’s set_widget_options

lino.core.inject.update_field(model_spec, name, **kw)

Update some attribute of the specified existing field. For example Human defines a field first_name, which may not be blank. If you inherit from this mixin but want first_name to be optional:

class MyPerson(mixins.Human):
    ...
dd.update_field(MyPerson, 'first_name', blank=True)

Or you want to change the label of a field defined in an inherited mixin, as done in lino_xl.lib.outbox:

dd.update_field(Mail, 'user', verbose_name=_("Sender"))

Note that you can update only certain attributes: verbose_name, blank, null, the precision and length of character or decimal fields, …

You cannot, for example, update the related_model of a ForeignKey field because this property causes a myriad of other things to happen during field initialization.

lino.core.inject.inject_quick_add_buttons(model, name, target)

Injects a virtual display field name into the specified model. This field will show up to three buttons [New] [Show last] [Show all]. target is the table that will run these actions. It must be a slave of model.