Welcome | Get started | Dive into Lino | Contribute | Topics | Reference | More

lino.core.utils

A collection of utilities which require Django settings to be importable.

Functions

DelayedValue(ar, fieldname, obj)

babel_values(*args, **kw)

babelattr(*args, **kw)

babelkw(*args, **kw)

class_dict_items(cl[, exclude])

db2param(spec)

Return a copy of the specified database field for usage as an actor parameter field.

dbfield2params_field(db_field)

originally just for setting up actor parameters from get_simple_parameters() but also used in calview.

djangoname(o)

error2str(self, e)

Convert the given Exception object into a string, but handling ValidationError specially.

format_request(request)

Format a Django HttpRequest for logging it.

full_model_name(model[, sep])

Returns the "full name" of the given model, e.g. "contacts.Person" etc.

get_field(model, name)

Returns the field descriptor of the named field in the specified model.

getrqdata(request)

Return the request data.

inrange_filter(fld, rng, **kw)

Assuming a database model with a field named fld, return a Q object to select those rows whose fld value is not null and within the given range rng.

is_devserver()

Returns True if this process is running as a development server.

is_logserver()

is_valid_email(s)

Returns True if the given string is a valid email.

is_valid_url(s)

Returns True if the given string is a valid URL.

model_class_path(model)

models_by_base(base[, toplevel_only])

Yields a list of installed models that are subclass of the given base class.

navinfo(qs, elem[, limit])

Return a dict with navigation information for the given model instance elem within the given queryset.

obj2str(i[, force_detailed])

Returns a human-readable ascii string representation of a model instance, even in some edge cases.

obj2unicode(i)

Returns a user-friendly unicode representation of a model instance.

qs2summary(ar, objects[, separator, max_items])

Render a collection of objects as a single paragraph.

range_filter(value, f1, f2)

Assuming a database model with two fields of same data type named f1 and f2, return a Q object to select those rows whose f1 and f2 encompass the given value value.

require_app_models(app_label)

resolve_app(app_label[, strict])

Return the modules module of the given app_label if it is installed.

resolve_field(name[, app_label])

Returns the field descriptor specified by the string name which should be either model.field or app_label.model.field.

resolve_fields_list(model, k[, ...])

resolve_model(model_spec[, app_label, strict])

Return the class object of the specified model.

sorted_models_list()

traverse_ddh_fklist(model[, ignore_mti_parents])

Return an iterator over each foreign key (in other models) that points to this model.

Classes

ParameterPanel(**kw)

A utility class for defining reusable definitions for parameters.

Parametrizable()

Base class for both Actors and Actions.

PseudoRequest(username)

A Django HTTP request which isn't really one.

UnresolvedField(name)

Returned by resolve_field() if the specified field doesn't exist.

UnresolvedModel(model_spec, app_label)

The object returned by resolve_model() if the specified model is not installed.

lino.core.utils.qs2summary(ar, objects, separator=', ', max_items=5, **kw)

Render a collection of objects as a single paragraph.

Parameters:
  • separator -- separator to use between objects.

  • max_items -- don't include more than the specified number of items.

lino.core.utils.getrqdata(request)

Return the request data.

Unlike the now defunct REQUEST attribute, this inspects the request's method in order to decide what to return.

lino.core.utils.is_valid_url(s)

Returns True if the given string is a valid URL. This calls Django's URLValidator(), but does not raise an exception.

lino.core.utils.is_valid_email(s)

Returns True if the given string is a valid email. This calls Django's validate_email(), but does not raise an exception.

lino.core.utils.is_devserver()

Returns True if this process is running as a development server.

Thanks to Aryeh Leib Taurog in How can I tell whether my Django application is running on development server or not?

My additions:

  • Added the len(sys.argv) > 1 test because in a wsgi application the process is called without arguments.

  • Not only for runserver but also for testserver and test.

  • pytest removes the first item from sys.argv when running doctests

lino.core.utils.format_request(request)

Format a Django HttpRequest for logging it.

This was written for the warning to be logged in lino.utils.ajax when an error occurs while processing an AJAX request.

lino.core.utils.full_model_name(model, sep='.')

Returns the "full name" of the given model, e.g. "contacts.Person" etc.

lino.core.utils.obj2unicode(i)

Returns a user-friendly unicode representation of a model instance.

lino.core.utils.obj2str(i, force_detailed=False)

Returns a human-readable ascii string representation of a model instance, even in some edge cases.

lino.core.utils.models_by_base(base, toplevel_only=False)

Yields a list of installed models that are subclass of the given base class.

If toplevel_only is True, then do not include MTI children. See Lino core utilities for more explanations.

The list is sorted alphabetically using full_model_name(). Before 2015-11-03 it was unpredictable and changed between Django versions.

lino.core.utils.range_filter(value, f1, f2)

Assuming a database model with two fields of same data type named f1 and f2, return a Q object to select those rows whose f1 and f2 encompass the given value value.

lino.core.utils.inrange_filter(fld, rng, **kw)

Assuming a database model with a field named fld, return a Q object to select those rows whose fld value is not null and within the given range rng. rng must be a tuple or list with two items.

class lino.core.utils.UnresolvedModel(model_spec, app_label)

Bases: object

The object returned by resolve_model() if the specified model is not installed.

We don't want resolve_model() to raise an Exception because there are cases of Database Migration where it would disturb. Asking for a non-installed model is not a sin, but trying to use it is.

I didn't yet bother very much about finding a way to make the model_spec appear in error messages such as AttributeError: UnresolvedModel instance has no attribute '_meta'. Current workaround is to uncomment the print statement below in such situations...

lino.core.utils.resolve_model(model_spec, app_label=None, strict=False)

Return the class object of the specified model. model_spec is usually the global model name (i.e. a string like 'contacts.Person').

If model_spec does not refer to a known model, the function returns UnresolvedModel (unless strict=True is specified).

Using this method is better than simply importing the class object, because Lino applications can override the model implementation.

This function does not trigger a loading of Django's model cache, so you should not use it at module-level of a models.py module.

In general we recommend to use from lino.api import rt and rt.models.contacts.Person over resolve_model('contacts.Person'). Note however that this works only in a local scope, not at global module level.

lino.core.utils.resolve_app(app_label, strict=False)

Return the modules module of the given app_label if it is installed. Otherwise return either the dummy module for app_label if it exists, or None.

If the optional second argument strict is True, raise ImportError if the app is not installed.

This function is designed for use in models modules and available through the shortcut dd.resolve_app.

For example, instead of writing:

from lino_xl.lib.trading import models as trading

it is recommended to write:

trading = dd.resolve_app('trading')

because it makes your code usable (1) in applications that don't have the 'trading' module installed and (2) in applications who have another implementation of the trading module (e.g. lino.modlib.auto.trading)

lino.core.utils.get_field(model, name)

Returns the field descriptor of the named field in the specified model.

class lino.core.utils.UnresolvedField(name)

Bases: object

Returned by resolve_field() if the specified field doesn't exist. This case happens when sphinx autodoc tries to import a module. See ticket https://gitlab.com/lino-framework/lino/blob/master/docs/tickets/4.

lino.core.utils.resolve_field(name, app_label=None)

Returns the field descriptor specified by the string name which should be either model.field or app_label.model.field.

lino.core.utils.navinfo(qs, elem, limit=None)

Return a dict with navigation information for the given model instance elem within the given queryset.

The returned dictionary contains the following keys:

Recno:

row number (index +1) of elem in qs

First:

pk of the first element in qs (None if qs is empty)

Prev:

pk of the previous element in qs (None if qs is empty)

Next:

pk of the next element in qs (None if qs is empty)

Last:

pk of the last element in qs (None if qs is empty)

Message:

text "Row x of y" or "No navigation"

Id_list:

list of the primary keys

Used by lino.core.actors.Actor.get_navinfo().

class lino.core.utils.Parametrizable

Bases: object

Base class for both Actors and Actions. See Introduction to actor parameters.

This is a pseudo-mixins that groups the common functionality for both actors and actions. It's not a real mixin because Actor must override every method as a class method (because actors are class objects while actions are class instances).

FOO_choices()

For every parameter field named "FOO", if the action has a method called "FOO_choices" (which must be decorated by dd.chooser()), then this method will be installed as a chooser for this parameter field.

check_params(pv)

Called when a request comes in.

class lino.core.utils.ParameterPanel(**kw)

Bases: object

A utility class for defining reusable definitions for parameters.

Subclassed e.g. by lino.mixins.periods.ObservedDateRange. lino_xl.lib.ledger.AccountingPeriodRange.

get_title_tags(ar)

A hook for specifying title tags for the actor which uses this parameter panel.

See lino.core.actor.Actor.get_title_tags().

check_values(pv)

Return an error message if the specified parameter values are invalid.

class lino.core.utils.PseudoRequest(username)

Bases: object

A Django HTTP request which isn't really one.

Typical usage example:

from lino.core.diff import PseudoRequest, ChangeWatcher

REQUEST = PseudoRequest("robin")

for obj in qs:
    cw = ChangeWatcher(obj)
    # update `obj`
    obj.full_clean()
    obj.save()
    cw.send_update(REQUEST)
lino.core.utils.error2str(self, e)

Convert the given Exception object into a string, but handling ValidationError specially.

lino.core.utils.dbfield2params_field(db_field)

originally just for setting up actor parameters from get_simple_parameters() but also used in calview.

lino.core.utils.db2param(spec)

Return a copy of the specified database field for usage as an actor parameter field.

A usage example is lino_xl.lib.tickets.SpawnTicket action. This action has two parameter fields, one for the type of link to create, the other for the summary of the ticket to create. We might copy the definitions of these to fields from their respective models and say:

parameters = dict(
    link_type=LinkTypes.field(default='requires'),
    ticket_summary=models.CharField(
        pgettext("Ticket", "Summary"), max_length=200,
        blank=False,
        help_text=_("Short summary of the problem."))
    )

But it is easier and more maintainable to say:

parameters = dict(
    link_type=db2param('tickets.Link.type'),
    ticket_summary=db2param('tickets.Ticket.summary'))

Unfortunately that doesn't yet work because actions get instantiated when models aren't yet fully loaded :-/

TODO: One idea to get it working is to say that parameter fields can be specified as names of fields, and Lino would resolve them at startup:

parameters = dict(
    link_type='tickets.Link.type',
    ticket_summary='tickets.Ticket.summary')
lino.core.utils.traverse_ddh_fklist(model, ignore_mti_parents=True)

Return an iterator over each foreign key (in other models) that points to this model. Used e.g. to predict the related objects that are going to be deleted in cascade when a database object is being deleted.

When an application uses MTI (e.g. with a Participant model being a specialization of Person, which itself a specialization of Partner) and we merge two Participants, then we must of course also merge their invoices and bank statement items (linked via a FK to Partner) and their contact roles (linked via a FK to Person).

See also #3891 (Lino says there are 2 related adresses when there is only one).