Record
Ein Record-Objekt stellt einen Datensatz einer App dar und hat folgende Attribute:
idString oderNoneDer eindeutige Datensatz-Identifizierer. Wurde das Datensatz-Objekt neu angelegt (durch Aufruf des App-Objektes) so ist
idnochNoneund wird erst beim Abspeichern (mittels save()) gesetzt.appAppDie App zu der dieser Datensatz gehört.
createdatDatumDer Zeitpunkt zu dem dieser Datensatz angelegt wurde.
createdbyUserDer Benutzer der diesen Datensatz angelegt hat.
updatedatDatum oderNoneDer Zeitpunkt zu dem dieser Datensatz zuletzt geändert wurde. Wurde der Datensatz noch nie geändert, so ist
updatedatNone.updatedbyUser oderNoneDer Benutzer, der den Datensatz zuletzt geändert hat. Wurde der Datensatz noch nie geändert, so ist
updatedbyNone.fieldsDictionary(String ➝ Field)fieldsbeinhaltet die Feld-Werte des Datensatzes. Einträge infieldshaben dieselbe Reihenfolge, wie die Einträge imcontrols-Attribut einesApp-Objekts. Die Schlüssel sind wieder die Feld-Identifizierer und die Werte sindField-Objekte.f_<identifier>FieldDie
Field-Objekte stehen auch über sogenannte „Shortcut“-Attribute zur Verfügung.record.fields.vornamesteht auch z.B. direkt alsrecord.f_vornamezur Verfügung.valuesDictionary(String ➝ Objekt)valuesbeinhaltet statt Field-Objekten direkt die Werte der Felder. Für alle Felderxgilt:record.fields.x.value is record.values.x
v_<identifier>ObjektAuch Feld-Werte stehen über „Shortcut“-Attribute zur Verfügung.
record.values.vornamealso z.B. alsrecord.v_vorname.
attachmentsDictionary(String ➝ Attachment)Die Anhänge zu diesem Datensatz. Die Dictionary-Schlüssel sind die Datenbank-Identifizierer des Anhangs, die Werte sind Attachment-Objekte.
childrenDictionary(String ➝ Dictionary(String ➝ Record))Die diesem Datensatz zugeordneten Datensätze. Der Dictionary-Schlüssel auf oberster Ebene ist dabei der Identifizierer, der dieser Zuordnung in der Konfiguration gegeben wurde. Das Dictionary auf zweiter Ebene beinhaltet die zugeordneten Datensätze. Die Schlüssel sind die Datensatz-Identifizierer und die Werte sind Record-Objekte. Als Sortierung wird die in der Konfiguration festgelegte Sortierung verwendet.
c_<identifier>Dictionary(String ➝ Record)Auch für zugeordnete Datensätze gibt es Shortcut-Attribute.
record.children.beispiel, steht auch direkt alsrecord.c_beispielzur Verfügung.detailsDictionary(String ➝ RecordChildren)Weitergehende Informationen zu den diesem Datensatz zugeordneten Datensätzen. Der Dictionary-Schlüssel ist dabei der Identifizierer, der dieser Zuordnung in der Konfiguration gegeben wurde. Die Werte sind RecordChildren-Objekte.
d_<identifier>RecordChildrenAuch für weitergehende Zuordnungsinformationen gibt es Shortcut-Attribute.
record.details.beispiel, steht auch direkt alsrecord.d_beispielzur Verfügung.errorsListe(String)Fehlermeldungen die den gesamten Datensatz betreffen als Liste von Strings. Diese werden im Augenblick nicht von System gesetzt, können aber vom Benutzer beliebig geändert werden.
add_error(error)Methode(String) ➝NoneFügt die übergebene Fehlermeldung zur Liste der Fehlermeldungen (
errors) hinzu. Diese Methode erwartet die Fehlermeldung als Argument. Das heißt, der Aufruf sieht beispielsweise so aus:record.add_error("Die Bearbeitungszeit ist abgelaufen!").has_errors()Methode() ➝ BoolGibt zurück, ob dieser Datensatz oder eines seiner Felder eine Fehlermeldung hat. Diese Methode erwartet keine Argumente. Das heißt, der Aufruf sieht beispielsweise so aus:
record.has_errors().clear_errors()Methode() ➝NoneLeert die Fehlermeldungs-Liste zu diesem Datensatz aber nicht die der Felder. Diese Methode erwartet keine Argumente. Das heißt der Aufruf sieht beispielsweise so aus:
record.clear_errors().clear_all_errors()Methode() ➝NoneLeert die Fehlermeldungs-Listen zu diesem Datensatz und zu den dazugehörigen Feldern. Diese Methode erwartet keine Argumente. Das heißt der Aufruf sieht beispielsweise so aus:
record.clear_all_errors().is_dirty()Methode() ➝ BoolGibt an, ob Feld-Werte geändert wurden. Ist der Datensatz noch gar nicht gespeichert, gibt
is_dirty()immerTruezurück.update(**values)Methode(**Objekt) ➝NoneMithilfe von
update()kann der Datensatz verändert werden. Die Parameter müssen per Schlüsselwort übergeben werden. Der Parametername ist dabei jeweils der Feld-Identifizierer des zu setzenden Feldes.D.h. ein Aufruf sieht z.B. so aus:
record.update(vorname="Max", nachname="Mustermann")
delete()Methode() ➝NoneMithilfe von
deletekann der Datensatz gelöscht werden. Diese Methode benötigt keine Parameter.Diese Methode kann auch aufgerufen, wenn der Datensatz noch gar nicht gespeichert wurde. In diesen Fall werden keine Datenbankänderungen vorgenommen.
Das Attribut
idwird nach dem Aufruf aufNonegesetzt und der Datensatz wird als gelöscht markiert und nachfolgende Aufrufe von save bleiben wirkungslos.
save(force, sync)Methode(Bool, Bool) ➝ BoolMit der Methode
savekann ein Datensatzobjekt abgespeichert werden. Ist dieses Datensatzobjekt neu angelegt (d.h.idistNone) wird beim Aufruf vonsaveein neuer Datensatz angelegt und beim Datensatzobjekt der eindeutige Datensatz-Identifizierer (id) vergeben, sowie die Attributecreatedbyaufglobals.user(eingeloggter Benutzer) undcreatedatauf das aktuelle Datum gesetzt. Ist das Datensatzobjekt nicht neu, werden beim Aufruf vonsavenur die geänderten Felder gespeichert, sowie das Attributupdatedbyaufglobals.userundupdatedatauf das aktuelle Datum gesetzt.Ist
forceFalse, so wird der Datensatz nicht gespeichert, wenn er oder einer seiner Felder eine Fehlermeldung hat (d.h. wennhas_errorsTruezurückgibt), oder wenn Felder von Typapplookup,multipleapplookupoderfileauf noch nicht gespeicherte Datensätze oder Dateien verweisen. Statt dessen wird ein Ausnahme-Fehler erzeugt, der die Ausführung des Anzeige-Templates abbricht. Dieser Ausnahme-Fehler kann dann unter oder angesehen werden.Ist
forceTrueso werden Fehlermeldungen am Datensatz oder seinen Feldern ignoriert, für noch nicht gespeicherte Datensätze oder Dateien wird stattdessenNoneals Wert verwendet und der Datensatz wird trotzdem gespeichert.Wenn für
syncFalseübergeben wird (der Default) ist das Verhalten wie oben beschrieben, wirdTrueübergeben, so wird nach dem Speichern dasRecord-Objekt mit dem Datenbank-Inhalt aktualisiert. Das heißt insbesondere, daß Änderungen die durch Datenaktionen an dem Datensatz durchgeführt wurden, imRecord-Objekt auftauchen.Der Rückgabewert von
savegibt an, ob der Datensatz tatsächlich in der Datenbank gespeichert wurde, oder ob dabei ein Fehler aufgetreten ist. Die entsprechende Fehlermeldung wird dabei an den Datensatz gehängt.Bemerkung
Für noch nicht gespeicherte Datensätze oder Dateien wird beim Speichern mit
force=Truezusätzlich eine Fehlermeldung an das Feld-Objekt gehängt (dies kann erst zum Speicherzeitpunkt gemacht werden, nicht zum Zeitpunkt der Zuweisung des Feld-Wertes, da es ja möglich ist, daß ein referenziertes Objekt erst gespeichert wird, nachdem es dem Feld zugewiesen wurde).Noch nicht gespeicherte Dateien können dabei bei der Verwendung innerhalb von Anzeige-Templates nicht auftreten, jedoch bei der Verwendung über das Python-SDK.
Bemerkung
Wurde vor dem Aufruf von
savedelete aufgerufen, bleibtsavewirkungslos, der Rückgabewert ist dannNone.executeaction(identifier)Methode(String) ➝NoneMithilfe von
executeactionkann eine Daten-Aktion auf dem Datensatz ausgeführt werden. Diese Daten-Aktionen können unter in der Aktionen-Maske definiert werden. Als Parameter muß der Identifizierer der Daten-Aktion übergeben werden.Gibt es z.B. eine Datenaktion mit dem Identifizierer
freigeben, so kann für den Datensatzrecorddiese Datenaktion folgendermaßen aufgerufen werden:<?code record.executeaction("freigeben")?>edit_embedded_url(**params)Methode(**Objekt) ➝ StringGibt die absolute URL zurück für das Eingabe-Formular zum Bearbeiten dieses Datensatzes. Bei dieser URL ist das Formular in den üblichen LivingApps-Rahmen eingebettet und der Benutzer muß eingeloggt sein um es benutzen zu können.
Mittels
paramskönnen der URL zusätzliche Parameter übergeben werden. Als Werte werden sowohl Strings unterstützt als auch Listen von Strings (in diesem Fall wird der Parameter mehrmals an die URL angefügt). Außerdem wird beim WertNoneder Parameter ignoriert.Beispiel 1:
<?print record.edit_embedded_url()?>
erzeugt:
https://my.living-apps.de/dateneingabe/1234567890abcdef12345678/10293848576afbecd12345678/edit
Beispiel 2:
<?print record.edit_embedded_url(view="abcdef12345678901234")?>
erzeugt:
https://my.living-apps.de/dateneingabe/1234567890abcdef12345678/10293848576afbecd12345678/edit?view=abcdef12345678901234
Beispiel 3:
<?print record.edit_embedded_url(a=["17", 23], b=None, c=[today(), None])?>
erzeugt:
https://my.living-apps.de/dateneingabe/1234567890abcdef12345678/10293848576afbecd12345678/edit?a=17&a=23&c=2022-11-10
edit_standalone_url(**params)Methode(**Objekt) ➝ StringGibt die absolute URL zurück für das Eingabe-Formular zum Bearbeiten dieses Datensatzes. Bei dieser URL ist das Formular nicht in den üblichen LivingApps-Rahmen eingebettet sondern unabhängig und kann auch von nicht eingeloggten Benutzern ausgefüllt werden.
Mittels
paramskönnen der URL zusätzliche Parameter übergeben werden.Beispiel 1:
<?print record.edit_standalone_url()?>
erzeugt:
https://my.living-apps.de/gateway/apps/1234567890abcdef12345678/10293848576afbecd12345678/edit
Beispiel 2:
<?print record.edit_standalone_url(view="abcdef12345678901234")?>
erzeugt:
https://my.living-apps.de/gateway/apps/1234567890abcdef12345678/10293848576afbecd12345678/edit?view=abcdef12345678901234
Beispiel 3:
<?print record.edit_standalone_url(a=["17", 23], b=None, c=[today(), None])?>
erzeugt:
https://my.living-apps.de/gateway/apps/1234567890abcdef12345678/10293848576afbecd12345678/edit?a=17&a=23&c=2022-11-10
display_embedded_url(**params)Methode(**Objekt) ➝ StringGibt die absolute URL für die Antwortseite zurück. Bei dieser URL ist die Seite in den üblichen LivingApps-Rahmen eingebettet und der Benutzer muß eingeloggt sein, um diese Seite angezeigt zu bekommen.
Mittels
paramskönnen der URL zusätzliche Parameter übergeben werden. Als Werte werden sowohl Strings unterstützt als auch Listen von Strings (in diesem Fall wird der Parameter mehrmals an die URL angefügt). Außerdem wird beim WertNoneder Parameter ignoriert.Beispiel 1:
<?print record.display_embedded_url()?>
erzeugt:
https://my.living-apps.de/dateneingabe/1234567890abcdef12345678/10293848576afbecd12345678/display
Beispiel 2:
<?print record.display_embedded_url(view="abcdef12345678901234")?>
erzeugt:
https://my.living-apps.de/dateneingabe/1234567890abcdef12345678/10293848576afbecd12345678/display?view=abcdef12345678901234
Beispiel 3:
<?print record.display_embedded_url(a=["17", 23], b=None, c=[today(), None])?>
erzeugt:
https://my.living-apps.de/dateneingabe/1234567890abcdef12345678/10293848576afbecd12345678/display?a=17&a=23&c=2022-11-10
display_standalone_url(**params)Methode(**Objekt) ➝ StringGibt die absolute URL für die Antwortseite zurück. Bei dieser URL ist die Seite nicht in den üblichen LivingApps-Rahmen eingebettet sondern unabhängig und kann auch von nicht eingeloggten Benutzern gesehen werden.
Mittels
paramskönnen der URL zusätzliche Parameter übergeben werden.Beispiel 1:
<?print record.display_standalone_url()?>
erzeugt:
https://my.living-apps.de/gateway/apps/1234567890abcdef12345678/10293848576afbecd12345678/display
Beispiel 2:
<?print record.display_standalone_url(view="abcdef12345678901234")?>
erzeugt:
https://my.living-apps.de/gateway/apps/1234567890abcdef12345678/10293848576afbecd12345678/display?view=abcdef12345678901234
Beispiel 3:
<?print record.display_standalone_url(a=["17", 23], b=None, c=[today(), None])?>
erzeugt:
https://my.living-apps.de/gateway/apps/1234567890abcdef12345678/10293848576afbecd12345678/display?a=17&a=23&c=2022-11-10
display_url(**params)Methode(**Objekt) ➝ StringGibt die absolute URL zurück für die Antwortseite. Mit dem System-Parameter
la_default_form_variantkann gesteuert werden, ob dieembeddedoder diestandaloneVariante erzeugt wird. Hat dieser den Wertstandalonewird diese Variante ausgespielt, sonstembedded(auch wenn der Parameter nicht angegeben wird).Beispiel 1:
<?print record.display_url()?>
erzeugt:
https://my.living-apps.de/dateneingabe/1234567890abcdef12345678/10293848576afbecd12345678/display
Beispiel 2:
<?print record.display_url(la_default_form_variant="standalone")?>
erzeugt:
https://my.living-apps.de/gateway/apps/1234567890abcdef12345678/10293848576afbecd12345678/display
Mit weiteren Parametern kann die Liste der Request-Parameter in der URL ergänzt werden. Beispiele hierfür finden sich in den Abschnitten display_embedded_url(**params) und display_standalone_url(**params).
template_url(identifier, /, **params)Methode(String, **Objekt) ➝ StringGibt die absolute URL zurück für ein Detail-Anzeige-Template mit dem Identifizierer
identifier. Die verlinkte App ist dabei die App zu der Datensatz gehört).Mittels
paramskönnen der URL zusätzliche Parameter übergeben werden.Beispiel 1:
<?print record.template_url("beispiel")?>
erzeugt:
https://my.living-apps.de/gateway/apps/1234567890abcdef12345678/10293848576afbecd12345678?template=beispiel
Beispiel 2:
<?print record.template_url("beispiel", x=17, y=23)?>
erzeugt:
https://my.living-apps.de/gateway/apps/1234567890abcdef12345678/10293848576afbecd12345678?template=beispiel&x=17&y=23
send_mail()Methode(from: String oderNone,reply_to: String oderNone,to: String oderNone,cc: String oderNone,bcc: String oderNone,subject: String oderNone,body_text: String oderNone,body_html: String oderNone, attachments: File oderNone) ➝NoneVerschickt eine E-Mail.
Nähere Informationen finden Sie unter E-Mails über die LivingAPI versenden.
count_child_records(filter)Methode(Dictonary(App ➝ String oder Liste von Strings)) ➝ IntegerGibt die Anzahl der Datensätze zurück, die über ein Applookup-Feld auf diesen Datensatz verweisen und die die vSQL-Bedingungen in
filtererfüllen.Als
filtermuß ein Dictionary übergeben werden mit den untergeordneten LivingApps als Schlüssel. Als Wert kann sowohl eine einzelne Filter-Bedingung übergeben werden, als auch eine Liste von Filter-Bedingungen. Diese werden dann mitandverknüpft. Die Filterbedingungen gelten nur für Datensätze aus der jeweiligen LivingApp, die als Schlüssel angegeben wurde. Aus LivingApps, die nicht als Schlüssel verwendet werden, werden keine Datensätze gezählt.Folgender Aufruf gibt beispielsweise die Anzahl der in den letzten 30 Tagen angelegten untergeordneten Datensätze zurück:
<?printx record.count_child_records( { c.app: "r.v_createdat >= now() - days(30)" for c in record.app.child_controls.values() } )?>
Hinweis
Um alle Datensätze zu zählen, kann folgender Code verwendet werden:
<?printx record.count_child_records( { c.app: "True" for c in record.app.child_controls.values() } )?>
delete_child_records(filter)Methode(Dictonary(App ➝ String oder Liste von Strings)) ➝ IntegerLöscht alle Datensätze die über ein Applookup-Feld auf diesen Datensatz verweisen und die die vSQL-Bedingungen in
filtererfüllen und gibt die Anzahl der gelöschten Datensätze zurück.Als
filtermuß ein Dictionary übergeben werden mit den untergeordneten LivingApps als Schlüssel. Als Wert kann sowohl eine einzelne Filter-Bedingung übergeben werden, als auch eine Liste von Filter-Bedingungen. Diese werden dann mitandverknüpft. Die Filterbedingungen gelten nur für Datensätze aus der jeweiligen LivingApp, die als Schlüssel angegeben wurde. Aus LivingApps, die nicht als Schlüssel verwendet werden, werden keine Datensätze gelöscht.Record-Objekte für gelöschte Datensätze werden als gelöscht markiert.
Folgender Aufruf löscht beispielsweise alle Datensätze, die nicht innerhalb der letzten 30 Tagen angelegt wurden (und gibt die Anzahl aus):
<?printx record.delete_child_records( { c.app: "r.v_createdat < now() - days(30)" for c in record.app.child_controls.values() } )?>
Hinweis
Um alle Datensätze zu löschen, kann folgender Code verwendet werden:
<?printx record.delete_child_records( { c.app: "True" for c in record.app.child_controls.values() } )?>
fetch_child_records(filter, sorts=None, offset=None, limit=None)Methode(Dictionary(App ➝ String oder Liste von Strings), String oder Liste von Strings oderNone, Integer oderNone, Integer oderNone) ➝ Dictionary(String ➝ Record)Gibt Datensätze zurück, die über ein Applookup-Feld auf diesen Datensatz verweisen und die die vSQL-Bedingungen in
filtererfüllen.Als
filtermuß ein Dictionary übergeben werden mit den untergeordneten LivingApps als Schlüssel. Als Wert kann sowohl eine einzelne Filter-Bedingung übergeben werden, als auch eine Liste von Filter-Bedingungen. Diese werden dann mitandverknüpft. Die Filterbedingungen gelten nur für Datensätze aus der jeweiligen LivingApp, die als Schlüssel angegeben wurde. Aus LivingApps, die nicht als Schlüssel verwendet werden, werden keine Datensätze zurückgegeben.sortslegt die Sortierreihenfolge fest. IstsortsNoneoder eine leere Liste werden die Datensätze in „natürlicher“ Reihenfolge zurückgegeben, ansonsten werden die Datensätze nach diesen Such-Ausdrücken sortiert. Istsortsein Liste von mehreren Strings erfolgt die Sortierung lexikografisch. Ein Sortierausdruck muß ein vSQL-Ausdruck sein, optional gefolgt vonascoderdesc, optional gefolgt vonnulls firstodernulls last. Diese vSQL-Ausdrücke können nur Felder verwenden, die alle Datensätze gemeinsam haben, d.h.id,createdat,createdby,updatedatoderupdatedby.Ist
offsetnichtNonemuß es eine nicht-negative Zahl sein, die festlegt wieviele Datensätze in der festgelegten Reihenfolge übersprungen werden, bevor Datensätze zurückgegeben werden (d.h. z.B. daßoffset=1den ersten Datensatz überspringt). IstoffsetNone(oder wird nicht übergeben) werden keine Datensätze übersprungen.Ist
limitnichtNonemuß es eine positive Zahl sein, die festlegt wieviele Datensätze (beginnend mit dem durchoffsetfestgelegten Start-Datensatz) insgesamt ausgegeben werden. IstlimitNone(oder wird nicht übergeben) werden alle Datensätze zurückgegeben.Der Rückgabewert ist ein Dictionary mit den Datensatz-IDs als Schlüssel und den Record-Objekten als Werte.
Folgender Aufruf benutzt das interne Template
App.la_vsql_searchum in allen untergeordnetetn Datensätze nachfoozu suchen, und die Datensätzn absteigen nach ihren Erzeugungsdatum zu sortieren:<?code records = record.fetch_child_records( { c.app: c.app.t_la_vsql_search("r", "foo") for c in record.app.child_controls.values() }, ["r.createdat desc"], )?>
Und folgender Aufruf gibt den neuesten geänderten untergeordneten Datensatz zurück:
<?code record = first(record.fetch_child_records( { c.app: "r.updatedat is not None" for c in record.app.child_controls.values() }, "r.createdat desc", limit=1, ).values())?>
fetch_child_recordpage(filter, sorts=None, offset=None, limit=None)Methode(Dictionary(App ➝ String oder Liste von Strings), String oder Liste von Strings oderNone, Integer oderNone, Integer oderNone) ➝ RecordChildenRecordPageGibt Datensätze zurück, die über ein Applookup-Feld auf diesen Datensatz verweisen und die die vSQL-Bedingungen in
filtererfüllen.Die Parameter haben dieselbe Bedeutung wie bei fetch_child_records(), jedoch wird das Resultat als RecordChildenRecordPage-Objekt zurückgegeben und nicht direkt als Dictionary.
customObjektDieses Attribut kann vom Benutzer für beliebige zusätzliche Informationen gesetzt werden.
x_<identifier>ObjektEs werden beliebige zusätzliche Attribute unterstützt deren Namen mit
x_beginnt.