20100213 Arbeitsbericht ======================================================= Ich habe die Idee, wie ich ContextAwareChoices besser implementieren kann (Issue 100): Die `city_choices`-Methode im Beispiel wird eine `@staticmethod` (braucht keine Instanz) und definiert selber ihre Liste von Argumenten, deren Name mit einem existierenden Feld übereinstimmen muss. Mit dieser API ist es möglich, dass das UserInterface (d.h. `extjs`) seine Combo-Boxen nicht jedesmal neu lädt, wenn der `current_record` ändert. Momentan wird beim Blättern durch Person (z.B.) der Context für jede Person neu geladen, auch wenn die neue Person im gleichen Land ist. Weil extjs bisher nicht wissen kann, dass für die Auswahlliste von `city` lediglich das Land wichtig ist. Aber wie kann ich in Python die Namen der deklarierten Argumente (formal parameter list) einer Funktion rausfinden? Mit `inspect`? Nö, viel einfacher: die stehen in `fn.func_code.co_argcount`. Ich probiere es aber lieber doch mal aus: http://code.google.com/p/lino/source/browse/tests/misc/choices.py Die Hauptarbeit wird darin bestehen, das momentane System der Comboboxen in extjs nochmal umzukramen... Dabei werde ich auch nochmal probieren, ob ich die Städtenamen in `cityHidden` nicht doch ausnutzen kann, um den Text der ComboBoxen anzuzeigen. Es ist einfach zu dumm, dass er beim einfachen Blättern durch die Persons jedesmal einen Request machen muss, um die Stadt anzuzeigen. In Zukunft kommt der Request dann zwar nur noch, wenn das Land der Person ändert. Aber auch das ist noch unnötig, weil die komplette Liste ja erst nötig ist, wenn man die Auswahlliste aufklappt. Frage am Rande: Bin ich nicht vielleicht das Rad neu am erfinden? Gibt es vielleicht doch schon andere Lösungen für das Problem der ContextAwareChoices? Das [http://www.djangosnippets.org/snippets/26/ Django Snippet 26] (Getting dynamic model choices in newforms) ist zunächst keine, aber in den Kommentaren werden zwei verschiedene Anzätze beschrieben "how to filter a lookup table based on a value passed at run time". Vor allem die Idee eines gewissen beuc ist bemerkenswert:: class MyForm(forms.ModelForm): class Meta: model = my_models.MyModel def __init__(self, *args, **kwargs): dynarg = kwargs.pop('dynarg') self.base_fields['myfield'].empty_label = None self.base_fields['myfield'].queryset = \ my_models.MyField.objects.filter(myfilter=dynarg) super(MyForm, self).__init__(*args, **kwargs) Also er setzt `FormField.queryset` beim Instanzieren der Form. Diese Idee nützt mir leider für ExtJS nichts, weil der Client die Dynamisierung machen muss (bzw. die Entscheidung, ob ein neuer Request nötig ist), d.h. die Entscheidung muss in JavaScript implementierbar sein. --- Weiter mit Issue 103 (das ich gerade erst erfasst habe, obschon ich ja schon die ganze Woche daran arbeite...) Mir ist inzwischen klar, dass ich das unmöglich mit einer normalen Grid geregelt kriege, sondern dafür muss eine `Ext.grid.PropertyGrid` her. Meine ersten Kennenlern-Versuche sind [http://code.google.com/p/lino/source/browse/extjs-showboxes/20100213_PropertyGrid.html hier]. Wieso finde ich `PropertyGrid.customRenderers` nicht im Quellcode? Aha, weil es eine neue Version 3.1.1 gibt. Das Feature ist offenbar neu, obwohl es nicht in den [http://www.extjs.com/products/extjs/CHANGES_ext-3.1.1.html Release notes] steht. `PropertyGrid.propertyNames` : super, dass es das gibt. Ich glaube, dass sollte ich prinzipiell benutzen, damit ich in mehrsprachigen Installationen keine Probleme kriege. Aber auf einsprachigen Sites (und insbesondere DSBE) hat das die lästige Nebenwirkung, dass ich mir für jede Eigenschaft einen internen Namen ausdenken muss. Hmm... also jedenfalls muss `Property.label` optional bleiben. Na das war ja einfach. Gefällt mir. Aber wie integriere ich das nun in Lino? Das ist mal was ganz Neues. Das wird eine neue Art von Element, das in einem PageLayout benutzt werden kann. Kommt also nach `layouts.py` als Klasse `PropertyGrid`. Die Klasse kann bis auf weiteres komplett leer sein, weil sie immer die `properties.PropValue` des `Report.model` anzeigt. Da sind also keine Konfigurationsoptionen. Und in `extjs.py` kommt eine neue Klasse `PropertyGridElement`. Die muss sich um das Einbinden kümmern. Jetzt wird es spannend. Aber ich geh trotzdem erst mal schlafen.