lino.core.inject

(This module's source code is available here.)

Functions

check_pending_injects(sender[, models_list])

django_patch()

Remove duplicate entries in the field cache of models to fix Django ticket Django ticket #10808.

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.

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)

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.

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.models:

dd.update_field(Mail, 'user', verbose_name=_("Sender"))
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.

lino.core.inject.django_patch()

Remove duplicate entries in the field cache of models to fix Django ticket Django ticket #10808.

See Diamond inheritance.