Dictionary in Django-Template rendern

Django, Flask, Bottle, WSGI, CGI…
Antworten
Benutzeravatar
nieselfriem
User
Beiträge: 135
Registriert: Sonntag 13. Januar 2013, 16:00

Hallo Zusammen,

ich bekomme es aktuell einfach nicht hin, dass ich mein Dictionary flexibel in eine bestimmte Form der Tabelle gerendert bekomme.

Das ist das beispielhafte Dictionary

Code: Alles auswählen

tolles_dict={"Standort1":{"url":"http://standort1", "id": "1", "parameter1": "value_param1_standort1", "parameter2": "value_param2_standort1",...,"parameterx": "value_paramx_standort1"},
             "Standort2":{"url":"http://standort1", "id": "2", "parameter2": "value_param1_standort2", "parameter2": "value_param2_standort2",...,"parameterx": "value_paramx_standort2"},....,
"Standortx":{"url":"http://standort1", "id": "1", "parameter1": "value_param1_standortx", "parameter2": "value_param2_standortx",...,"parameterx": "value_paramx_standortx"}         
             }
und das ist die Tabelle, die ich rendern möchte

Code: Alles auswählen

<html>
<table border="1">
    <tr>
        <td></td>
        <td>Standort1</td>
        <td>Standort2</td>
        <td>...</td>
        <td>Standortx</td>
    </tr>
    <tr>
        <td>url</td>
        <td>http://standort1</td>
        <td>http://standort2</td>
        <td>...</td>
        <td>http://standortx</td>
   </tr>
    <tr>
        <td>id</td>
        <td>1</td>
        <td>2</td>
        <td>...</td>
        <td>x</td>
    </tr>
    <tr>
        <td>parameter1</td>
        <td>value_param1_standort1</td>
        <td>value_param1_standort2</td>
        <td>...</td>
        <td>value_param1_standortx</td>
    </tr>
    <tr>
        <td>parameter2</td>
        <td>value_param2_standort1</td>
        <td>value_param2_standort2</td>
        <td>...</td>
        <td>value_param2_standortx</td>
    </tr>
    <tr>
        <td>...</td>
        <td>...</td>
        <td>...</td>
        <td>...</td>
        <td>...</td>
    </tr>
    <tr>
        <td>parameterx</td>
        <td>value_paramx_standort2</td>
        <td>value_paramx_standort2</td>
        <td>...</td>
        <td>value_paramx_standortx
    </tr>
</table>
</html>
aktuell habe ich folgendes

Code: Alles auswählen

 <tr>
            <td></td>
            {% for standort in tolles_dict %}
                <td>{{ standort }}</td>
            {% endfor %}
        </tr>
        {% for standort_name, standort_values in tolles_dict.items %}
            {% for key, value in standort_values.items %}
                <tr>
                    <td>{{ key }}</td>
                      {% for standort_name, standort_kvalues in tolles_dict.items %}
                        <td>{{ value }}</td>
                    {% endfor %}
                </tr>
            {% endfor %}
        {% endfor %}
Der werden zwar die Standortnamen im header richtig gerendert und die Parameternamen am linken Rand. Jedoch werden für alle Standorte immer nur die gleichen Werte der Parameter eingetragen.

Es wird also statt value_param1_standort2 für den Standort2 der value_param1_standort1 geschrieben.

Ich komme hierbei irgendwie nicht weiter. Ich nehme an, dass die Lösung sehr einfach ist. Aber der Knoten im Kopf platzt aktuell einfach nicht ;)

VG niesel
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Die innerste Schleife ist ja auch ziemlich sinnfrei weil weder `standort_name` noch `standort_kvalues` verwendet werden und die Schleife geht auch nochmal über `tolles_dict` und nicht über das verschachtelte Wörterbuch aus der äusseren Schleife. Da hilft vielleicht auch die Sachen mal sinnvoll zu benennen statt so generische Namen, damit man nicht nur als Leser, sondern auch als Autor weiss was sich hinter den Namen verbirgt. 😛
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
nieselfriem
User
Beiträge: 135
Registriert: Sonntag 13. Januar 2013, 16:00

Code: Alles auswählen

  
<tr>
            <td></td>
            {% for standort_name in tolles_dict %}
                <td>{{ standort_name }}</td>
            {% endfor %}
        </tr>
        {% for standort_name, standort_values in tolles_dict.items %}
            {% for param_name, param_value in standort_values.items %}
                <tr>
                <td>{{ param_name }}</td>
                </tr>
            {% endfor %}
        {% endfor %}
Das verstehe ich. Jetzt ist es aktuell so, dass er schön die Parameternamen mit param_name auf der linken Seite rendert. Aber ich bekomme es einfach nicht hin, dass er ab der zweiten spalte durch die Standorte iteriert und dort die Parametervalues nebeneinander in die Spalten schreibt.

VG
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Man muss dann erst durch die Schlüssel der Standortdaten iterieren, und dann für jeden Schlüssel alle Standorte. So was in der Richtung hier (ungetestet):

Code: Alles auswählen

<table>
  <thead>
    <tr>
      <th></th>
      {% for standort_name in tolles_dict %}
        <th>{{ standort_name }}</th>
      {% endfor %}
    </tr>
  </thead>
  <tbody>
    {% for param_name in next(iter(tolles_dict.values()), {}).keys() %}
      <tr>
        <td>{{ param_name }}</td>
        {% for standort_values in tolles_dict.values() %}
          <td>{{ standort_values[param_name] }}</td>
        {% endfor %}
      </tr>
    {% endfor %}
  </tbody>
</table>
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
nieselfriem
User
Beiträge: 135
Registriert: Sonntag 13. Januar 2013, 16:00

Code: Alles auswählen

{% for param_name in next(iter(tolles_dict.values()), {}).keys() %}
mag Django-Template nicht. Ich gucke mir das morgen mal an und melde mich. Danke für deine zeit.


VG
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Kommt halt drauf an welche Funktionen zur Verfügung stehen. Man könnte auch die Daten für die Anzeige vor dem Template schon passender/freundlicher aufbereiten.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
nieselfriem
User
Beiträge: 135
Registriert: Sonntag 13. Januar 2013, 16:00

Hallo zusammen,

lange rede kurzer Sinn. So habe ich es am Ende auch gemacht. Ich habe aus dem Dictionary über diese FUnktion eine zweidimensionale Liste gebaut.

Code: Alles auswählen

    @logger.catch
    def create_render_list_param_monitor(self, param_dictionary):
        keys = list(param_dictionary.keys())
        header = [''] + keys
        rows = []
        for k in param_dictionary[keys[0]]:
            row = [k]
            for key in keys:
                row.append(param_dictionary.get(key).get(k, ""))
            rows.append(row)

        result = [header] + rows
        return result
und habe diese dann hiermit im Template rendern lassen

Code: Alles auswählen

 <table style="width:100%" id="paramtable" class="scrolltable">
        {% for inner_array in render_param_infos_actuator_list %}
            {% if forloop.first %}
                <thead>
                <tr>
                    {% for item in inner_array %}
                        <th>{{ item }}</th>
                    {% endfor %}
                </tr>
                </thead>
                <tbody>
            {% else %}
                <tr>
                    {% for item in inner_array %}
                        {% if forloop.counter0 >= 1 %}
                            {% if forloop.parentloop.counter0 == 1 %}
                                <td><a href="{{ item }}">{{ item }}</a></td>
                            {% else %}
                                <td>{{ item }}</td>
                            {% endif %}
                        {% else %}
                            <td>{{ item }}</td>
                        {% endif %}
                    {% endfor %}
                </tr>
            {% endif %}
        {% endfor %}
    </table>
Danke für den Denkanstoß.

VG niesel
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@nieselfriem: Die ”Methode” ist gar keine Methode. Das sollte entweder eine Funktion ausserhalb der Klasse sein, oder eine `statichmethod()`.

Der erste `get()`-Aufruf wäre besser nur ein Schlüsselzugriff, denn der *muss* funktionieren, denn `None` hat keine `get()`-Methode.

Die Funktion lässt sich auch ohne Schleifen und fast alle benannten Zwischenergebnisse direkt als Liste und mit „comprehensions“ ausdrücken. Dann sieht man die Ergebisstruktur deutlicher am Code.

Ungetestet:

Code: Alles auswählen

@logger.catch
def create_render_list_param_monitor(param_dictionary):
    outer_keys = list(param_dictionary.keys())
    return [
        ["", *outer_keys],
        *(
            [
                inner_key,
                *(
                    param_dictionary[outer_key].get(inner_key, "")
                    for outer_key in outer_keys
                ),
            ]
            for inner_key in param_dictionary[outer_keys[0]].keys()
        ),
    ]
Wobei das mit den ganzen generischen Namen und zweimal Schlüsseln (`k` und `key`) alles ein bisschen schlecht lesbar ist. Da würde ich mindestens mal ein kleines Beispiel in einen Docstring packen. Dann hätte man auch gleich einen (Doc)Test.

Und das ganze funktioniert nur mit einem Wörterbuch als Argument, das mindestens einen Eintrag hat.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten