Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More
More chooser examples¶
Side note: Code snippets (lines starting with >>>
) in this document get
tested as part of our development workflow. The following
initialization snippet tells you which demo project is being used in
this document.
>>> from lino import startup
>>> startup('lino_book.projects.noi1e.settings.demo')
>>> from lino.api.doctest import *
Choosers that need the requesting user¶
If your chooser method needs to know the current user to determine the choices for a field, include a “ar” parameter to your chooser method:
@dd.chooser()
def food_choices(cls, ar):
year_in_school = ar.get_user().year_in_school if ar is not None else None
food = []
for name, reserved_for in MENU:
if (year_in_school
is None) or (reserved_for
is None) or year_in_school in reserved_for:
food.append(name)
return food
For example the chooser for the lino_xl.lib.tickets.Ticket.group
field
wants to know who is asking before deciding which choices to display, because
not everybody can see every site.
>>> url = '/choices/tickets/Ticket/group'
>>> show_choices("robin", url)
<br/>
Developers
Managers
Sales team
>>> show_choices("luc", url)
<br/>
Developers
Sales team
Some special cases¶
Asking choices for a field that doesn’t exist:
>>> show_choices("robin", '/choices/tickets/Ticket/foo')
Traceback (most recent call last):
...
AttributeError: 'NoneType' object has no attribute 'blank'
Asking choices for a field that exists but has no choices:
>>> show_choices("robin", '/choices/tickets/Ticket/summary')
Traceback (most recent call last):
...
Exception: Response status (/choices/tickets/Ticket/summary) was 404 instead of 200
When asking the choices for a field on a slave table, you must specify the master instance (even though it is not relevant):
>>> url = '/choices/tickets/TicketsByType/group?mk=1'
>>> show_choices("robin", url)
<br/>
Developers
Managers
Sales team
When lino.core.site.Site.strict_master_check
is True,
not specifying a master key when asking the choices for a field on a slave table
is an error:
>>> settings.SITE.strict_master_check = True
>>> url = '/choices/tickets/TicketsByType/group'
>>> show_choices("robin", url)
Traceback (most recent call last):
...
Exception: Response status (/choices/tickets/TicketsByType/group) was 400 instead of 200
lino.modlib.comments.CommentsByRFC
is a slave table whose
master field is a GFK. In that case you must also specify the master type;
the master key is not enough.
>>> comments.CommentsByRFC.master_field
<lino.modlib.gfks.fields.GenericForeignKey: owner>
>>> comments.CommentsByRFC.master_field.name
'owner'
A correct call:
>>> url = '/choices/comments/Comments/owner_id?mk=12&mt=38&owner_type=43&limit=3'
>>> show_choices("robin", url)
<br/>
#1 (Föö fails to bar when baz)
#2 (Bar is not always baz)
#3 (Baz sucks)
A call without mt
is allowed because the master type (here Comment) is
known:
>>> show_choices("robin", '/choices/comments/CommentsByRFC/reply_to?mk=12&limit=3')
<br/>
Comment #1
Comment #2
Comment #3
The following snippet was used to reproduce #5440 (Changing the ticket of a comment doesn’t work):
>>> contenttypes.ContentType.objects.get_for_model(tickets.Ticket).pk
43
>>> comment = comments.Comment.objects.filter(owner_id=105, owner_type=43).first()
>>> comment
Comment #414 ('Comment #414')
>>> comment.owner
Ticket #105 ('#105 (Irritating message when bar)')
>>> comments.CommentsByRFC.master
<class 'django.contrib.contenttypes.models.ContentType'>
>>> url = '/choices/comments/CommentsByRFC/owner_id?mk=105&mt=43&owner_type=43&limit=3'
>>> show_choices("robin", url)
<br/>
#1 (Föö fails to bar when baz)
#2 (Bar is not always baz)
#3 (Baz sucks)