20120527¶
Oops, Lino hatte einen auffallenden Bug, der mir aber jetzt erst aufgefallen ist:
das Detail einer Person zeigte das Detail des Partners.
Das lag an lino.core.actors.Actor._collect_actions()
.
Die detail_action und insert_action müssen für jeden Actor eigens instanziert werden
Und noch ein subtiler Bug:
lino.ui.extjs3.ext_elems.DisplayElement muss das Ext.form.displayField
mit einem Defaultwert von <br/>
generieren, denn in einem Layout wo nur solche Felder in einer Zeile stehen,
gibt er ansonsten beim Rendern die falsche Höhe an, so dass das GridElement
sich zu viel Platz einnimmt. Das Ganze passiert nur dann, wenn wir den Bildschirm
über den permalink laden.
Beispiel:
Zur eigentlichen Sache. Der [Add]-Link dort unter Manage Access hat folgende URL:
javascript:Lino.cbss.ManageAccessRequestsByPerson.insert_action(null,{ "data_record": { "phantom": true, "data": { "sector": 0, "statusHidden": null, "last_name": "", "national_id": "", "response_xml": "", "result": "", "id_card_no": "", "actionHidden": null, "id": null, "first_name": "", "query_registerHidden": null, "sis_card_no": "", "query_register": null, "userHidden": 2, "personHidden": 113, "environment": "", "disabled_fields": { }, "start_date": null, "sent": null, "status": null, "end_date": null, "disable_editing": false, "birth_date": "", "user": "Root User", "ticket": "", "person": "ARENS Andreas (113)", "action": null, "purpose": 0 }, "title": "ManageAccess Requests von ARENS Andreas (113)" }, "base_params": { "mt": 20, "mk": 113 } })
Was ich da vermisse, sind die Defaultwerte für last_name, first_name, query_register usw. Das kommt daher, dass ich die in einer on_create setze. Aber on_create ist gefährlich, weil man Vererbung selbst regeln muss. Sie kann ja kein super() rufen, weil Model so eine Methode nicht hat. Lino rief dann die on_create von AutoUser auf und die NISS.on_create blieb ungerufen. Also on_create ist eine lästige Mausefalle, aber ich sehe momentan keine bessere Lösung. Ist auch nicht so dringend.
javascript:Lino.cbss.ManageAccessRequestsByPerson.insert_action(null,{ “data_record”: { “phantom”: true, “data”: { “sector”: 0, “statusHidden”: null, “last_name”: “Arens”, “national_id”: “”, “response_xml”: “”, “result”: “”, “id_card_no”: “”, “actionHidden”: null, “id”: null, “first_name”: “Andreas”, “query_registerHidden”: null, “sis_card_no”: “”, “query_register”: null, “userHidden”: 2, “personHidden”: 113, “environment”: “”, “disabled_fields”: { }, “start_date”: null, “sent”: null, “status”: null, “end_date”: null, “disable_editing”: false, “birth_date”: “”, “user”: “Root User”, “ticket”: “”, “person”: “ARENS Andreas (113)”, “action”: null, “purpose”: 0 }, “title”: “ManageAccess Requests von ARENS Andreas (113)” }, “base_params”: { “mt”: 20, “mk”: 113 } })
Ein anderes Problem ist die Tatsache, das der default-Wert meiner
ChoiceListField
offenbar ignoriert wird. Bei näherer Untersuchung sehe ich, dass
wenn ein Feld einen default hat, Django diesen bei der Instanzierung
des Models in einen String umwandelt:
def get_default(self):
"""
Returns the default value for this field.
"""
if self.has_default():
if callable(self.default):
return self.default()
return force_unicode(self.default, strings_only=True)
if (not self.empty_strings_allowed or (self.null and
not connection.features.interprets_empty_strings_as_nulls)):
return None
return ""
def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
"""
...
If strings_only is True, don't convert (some) non-string-like objects.
"""
...
if strings_only and is_protected_type(s):
return s
def is_protected_type(obj):
return isinstance(obj, (
types.NoneType,
int, long,
datetime.datetime, datetime.date, datetime.time,
float, Decimal)
)
Der default-Wert meiner Felder ist nun aber eine
lino.utils.choicelists.BabelChoice
-Instanz,
Django kennt die nicht und ruft folglich deren unicode()
auf. Doof. Also auch z.B. eine Model-Instanz könnte man
nicht als default-Wert angeben. Wie die Django-Entwickler
auf diese Idee kamen, ist mir unklar.
Und so wie ich die kenne, werden sie wohl kaum was daran ändern.
Interessanterweise macht er das force_unicode() nicht,
wenn default ein callable ist.
Workarounds:
Ich setze keinen default-Wert, sondern fülle das Feld in meiner on_create.
Ich mache
lino.utils.choicelists.BabelChoice
callable:def __call__(self): return self
Beide Workarounds funktionieren, und ich entscheide mich bis auf Weiteres für den zweiten, weil der mir eleganter scheint. Bin zwar nicht sicher, ob das keine Nebenwirkungen hat. Aber das werden wir dann eben sehen.
Miscellaneous:
Moved
ChoiceListField
fromlino.core.fields
tolino.utils.choicelists
because that’s the only module which uses it directly.CBSSRequest is no longer ProjectRelated, this mixin seems not very useful, at least here. Field project replaced by person.