20110128

Person Searches

Neues Model PersonSearch für erweiterte Personensuche. Insbesondere der Slave-Report PersonsBySearch war technisch noch eine Herausforderung, weil es erstmals ein Slave-Report ohne fk_name ist.

Das proof of concept funktionierte nach nur einer Stunde!

Der Code zum Aufbau des SQL-Querys ist in der Methode get_request_queryset, und ist schon jetzt recht komplex. Um Personen zu finden, die bestimmte Sprachkenntnisse oder Fähikeiten haben, habe ich ein bisschen überlegen müssen wie das Query aufzubauen ist.

Ein erster Versuch funktionierte zwar, aber war noch suboptimal:

  required_lk = [lk for lk in search.searchedlanguageknowledge_set.all()]
  if required_lk:
      l = []
      for p in qs:
          for rlk in required_lk:
              try:
                  plk = p.languageknowledge_set.get(language__exact=rlk.language)
                  l.append(p)
              except LanguageKnowledge.DoesNotExist:
                  pass
      return l

Also statt eines QuerySets gibt er eine einfache Liste zurück, wenn man in
"Required language knowledges"
eine (oder mehrere) Sprachen angibt.
Ich wüsste nämlich (noch) nicht, wie ich diese Bedingung als Django-Query
formulieren könnte...
Das Problem wenn ich eine Liste zurück gebe ist, dass dann das Sortieren und
die Kolonnenfilter nicht mehr funktionieren.

Um zu sehen, wie ich’s jetzt mache, siehe source code. Die Schönheit dieses Codes haben wir übrigens nicht Lino, sondern Python und Django zu verdanken.

Änderungen Datenmodel “Fähigkeiten und Hindernisse”

Durch das neue Suchmodul ist mir klar geworden, dass noch folgende Änderungen im Datenmodel angebracht sind:

  1. Das Feld “IT-Kenntnisse” kommt raus. Logischer ist es, wenn es stattdessen eine Fähigkeit namens “IT-Kenntnisse” gibt.

  2. Die Hindernisse kommen ebenfalls wie die Fähigkeiten in einer eigenen Tabelle, statt wie bisher als 16 Ankreuzfelder.

    Vorteile: - Liste der Hindernisse wird konfigurierbar - Ein Reiter weniger, insgesamt übersichtlicher

    Nachteile: - man kann nicht mehr bequem am Bildschirm auswählen und anklicken, sondern muss (wie bei den Fähigkeiten) eine Tabelle füllen und jedes einzelne Hindernis aus der Auswahlliste raussuchen. - Evtl. Tipparbeit bei der Datenmigration

Diese Änderungen haben dann eine kleine Entwicklungslawine ausgelöst. Eine erste Lösung sah wie folgt aus (aber das alles habe ich am WE nochmal umgekrempelt, Praktiker lesen also jetzt hier weiter. Für Historiker hier noch der Stand meiner Ideen von heute abend:

  1. Wenn wir schon dabei sind:

    Skill wird umbenannt nach OwnedSkill, SkillType nach Skill,

  2. und dann kriegen wir ein neues Konzept von “skill type”, die aber keine dynamisch konfigurierbare Liste sind, sondern im Code definiert werden:

    1 Skills Fachkompetenzen
    2 Soft skills Sozialkompetenzen
    3 Obstacles Hindernisse

    Die bisherigen “Fähigkeiten & Hindernisse” kommen also in diese Liste von skill types, wobei wir die Fähigkeiten gleich unterteilen in Fach- und Sozialkompetenzen.

    Die beiden SkillOccurence-Modelle haben jetzt zwei Felder, um die Fähigkeit zu definieren. Der Typ (type) ist theoretisch nicht nötig, weil der ja auch schon im Skill steht. Aber das ist für später mal, das kriegt Lino momentan noch nicht auf die Reihe.

    Ich hätte das in drei verschiedenen Modellen machen können, aber weil die sich so ähnlich sind, fand ich diese (neue) Methode von halbdynamischen Definitionen sinnvoll. Es hat keinen Zweck, die Dinger dynamisch konfigurierbar zu machen, weil dann auch die .dtl-Dateien und das Menü angepasst werden müssen.

  3. TODO:

    • Skill types lokal (im LinoSite) konfigurierbar machen
    • class SkillType?
    • Untermenü
    • “Eigenschaften” -> “Kontaktarten”
    • Skills -> Eigenschaften
    • Auswahlmöglichkeiten konfigurierbar (statt StrengthField)