Learning foreign keys¶
The application developer can turn any foreign key field into a learning foreign key.
- learning foreign key
A foreign key that can "learn", i.e. add new items to its list of choices.
- learning chooser
The chooser associated to a learning foreign key.
Usage¶
Define a chooser for the field by defining a
FOO_choices()
method on the model and decorating it with@dd.chooser
.Define an instance method
create_FOO_choice
on the model.Example from
lino_xl.lib.countries.CountryCity
:def create_city_choice(self, text): if self.country is not None: return rt.models.countries.Place.lookup_or_create( 'name', text, country=self.country) raise ValidationError( "Cannot auto-create city %r if country is empty", text)
Example from
lino_xl.lib.contacts.Person
:def create_person_choice(self, text): return rt.models.contacts.Person.create_from_choice(text)
When you use the
lino.core.model.Model.create_from_choice()
method, you probably want to override the model'slino.core.model.Model.choice_text_to_dict
method of the related model.
Examples¶
The city
field of a postal
address. When you specify the name of a city that does not yet exist, you simply
leave the "invalid" city name in the combobox (Lino accepts it) and save the
partner. Lino will then silently create a city of that name. Note that you must
at least set the country
, otherwise Lino refuses to automatically create
a city. This behaviour is defined in the countries.CountryCity
model mixin, which is inherited e.g. by
contacts.Partner
. or
addresses.Address
Or the lino_xl.lib.contacts.Role.person
field. You can see the new
feature in every application with contacts. For example
lino_book.projects.min1
. In the detail of a company, you have the
RolesByCompany
slave table. In
the Person column of that table you can type the name of a person that does
not yet exist in the database. Lino will create it silently, and you can then
click on the pointer to edit more information.
Some examples in Automatically creating contact persons.
Implementation details¶
When a method is decorated with the chooser decorator, Lino creates a
lino.utils.choosers.Chooser
instance. The can_create_choice
attribute of this instance will
automatically be set to True when the field's model also has a method named
create_FOO_choice
(FOO being the field name).