Mako Template und Python: Verwaltungssoftware

Django, Flask, Bottle, WSGI, CGI…
Antworten
breedi
User
Beiträge: 10
Registriert: Freitag 28. Oktober 2016, 18:50

Guten Abend,

Ich habe folgendes Problem: Ich möchte das Template-Framework Mako verwenden und bin wie folgt vorgegangen, er erkennt alles prima, nur wenn er die Listenwerte ausgeben soll, macht er was er will.

Code: Alles auswählen

import codecs
import os.path
import string

from mako.template import Template
from mako.lookup import TemplateLookup

#----------------------------------------------------------
class View_cl(object):
#----------------------------------------------------------

    #-------------------------------------------------------
    def __init__(self, path_spl):
	#-------------------------------------------------------
	    self.path_s = os.path.join(path_spl, "template")
	    self.lookup_o = TemplateLookup(directories=[self.path_s])
		
	#-------------------------------------------------------
    def create_p(self, template_spl, data_opl):
	    template_o = self.lookup_o.get_template(template_spl)
	    return template_o.render(data_o = data_opl)


    def createList_px(self, data_opl):
	#Templategenerierung der Firmendaten
	    return self.create_p('liste.tpl', data_opl)
Listenstruktur:

Code: Alles auswählen

    
def save(self, **data_opl):
	# Savefunktion für das Firmenverzeichnis
	    # Sichern der Daten: aufgrund der Formularbearbeitung muss
		# eine vollständige HTML-Seite zurückgeliefert werden!
		
		# data_opl: Dictionary mit den gelieferten key-value-Paaren
		
		# hier müsste man prüfen, ob die Daten korrekt vorliegen!
		
	    id_s = data_opl["id_s"]
	    data_a =[ data_opl["firmenname"]
	    ,   data_opl["branche"]
	    ,   data_opl["taetigkeit"]
	    ,   data_opl["sitz"]
	    ,   data_opl["anzahl"]

		]
[codebox=html5 file=liste.tpl]
## coding: utf-8
<table id="idList">
<tr><th>Firmenname</th><th>Branche</th><th>Taetigkeit</th><th>Sitz</th><th>Anzahl</th></tr>
## man verwendet hier Zugriff auf das Dictionary "data_o"
% for id_s in data_o:
<tr id="r${id_s}">
<td>${data_o[id_s]['firmenname']}</td>
<td>${data_o[id_s]['branche']}</td>
<td>${data_o[id_s]['taetigkeit']}</td>
<td>${data_o[id_s]['sitz']}</td>
<td>${data_o[id_s]['anzahl']}</td>
</tr>
% endfor
[/code]

Wenn ich denn die Seite besuchen will, in der er die Template-Engine erzeugen möchte gibt er mir folgenden Fehler aus. Ich habe darauf geachtet die Listenwerte gesondert auszugeben mittlerweile weiß ich echt nichtmehr weiter und die Dokumentationen von Mako hilft auch nicht sehr viel.

127.0.0.1 - - [02/Nov/2016:21:04:29] "GET /praxisphasenangebot HTTP/1.1" 200 6979 "http://127.0.0.1:8080/" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0"
[02/Nov/2016:21:04:34] HTTP
Traceback (most recent call last):
File "C:\Users\thomas\AppData\Local\Programs\Python\Python35-32\lib\site-packages\cherrypy-8.1.2-py3.5.egg\cherrypy\_cprequest.py", line 670, in respond
response.body = self.handler()
File "C:\Users\thomas\AppData\Local\Programs\Python\Python35-32\lib\site-packages\cherrypy-8.1.2-py3.5.egg\cherrypy\lib\encoding.py", line 220, in __call__
self.body = self.oldhandler(*args, **kwargs)
File "C:\Users\thomas\AppData\Local\Programs\Python\Python35-32\lib\site-packages\cherrypy-8.1.2-py3.5.egg\cherrypy\_cpdispatch.py", line 60, in __call__
return self.callable(*self.args, **self.kwargs)
File "C:\Users\thomas\PycharmProjects\web_prak2\p2\ppm\app\application.py", line 29, in firmenverwaltung
return self.createList_p()
File "C:\Users\thomas\PycharmProjects\web_prak2\p2\ppm\app\application.py", line 159, in createList_p
return self.view_o.createList_px(data_o)
File "C:\Users\thomas\PycharmProjects\web_prak2\p2\ppm\app\view.py", line 36, in createList_px
return self.create_p('liste.tpl', data_opl)
File "C:\Users\thomas\PycharmProjects\web_prak2\p2\ppm\app\view.py", line 31, in create_p
return template_o.render(data_o = data_opl)
File "C:\Users\thomas\AppData\Local\Programs\Python\Python35-32\lib\site-packages\mako-1.0.4-py3.5.egg\mako\template.py", line 445, in render
return runtime._render(self, self.callable_, args, data)
127.0.0.1 - - [02/Nov/2016:21:04:34] "GET /firmenverwaltung HTTP/1.1" 500 823 "http://127.0.0.1:8080/praxisphasenangebot" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0"
File "C:\Users\thomas\AppData\Local\Programs\Python\Python35-32\lib\site-packages\mako-1.0.4-py3.5.egg\mako\runtime.py", line 829, in _render
**_kwargs_for_callable(callable_, data))
File "C:\Users\thomas\AppData\Local\Programs\Python\Python35-32\lib\site-packages\mako-1.0.4-py3.5.egg\mako\runtime.py", line 864, in _render_context
_exec_template(inherit, lclcontext, args=args, kwargs=kwargs)
File "C:\Users\thomas\AppData\Local\Programs\Python\Python35-32\lib\site-packages\mako-1.0.4-py3.5.egg\mako\runtime.py", line 890, in _exec_template
callable_(context, *args, **kwargs)
File "liste_tpl", line 26, in render_body
TypeError: list indices must be integers or slices, not str
[02/Nov/2016:21:04:34] HTTP
Request Headers:
ACCEPT-LANGUAGE: de,en-US;q=0.7,en;q=0.3
ACCEPT-ENCODING: gzip, deflate
USER-AGENT: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0
CONNECTION: keep-alive
ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HOST: 127.0.0.1:8080
Remote-Addr: 127.0.0.1
REFERER: http://127.0.0.1:8080/praxisphasenangebot
UPGRADE-INSECURE-REQUESTS: 1
Hier nochmal das komplette Projekte für die Tiefeneinsicht.

https://hs-niederrhein.sciebo.de/index. ... Vp399W712v
Zuletzt geändert von breedi am Mittwoch 2. November 2016, 21:29, insgesamt 2-mal geändert.
BlackJack

@breedi: Das hat ja nicht wirklich was mit Mako zu tun. Wie sieht denn `data_o` in dem Template aus? Ich dachte Du hast ein Wörterbuch das IDs auf *Listen* mit dem Werten abbildet. Und wie die Fehlermeldung sagt kann man auf Listen nicht mit Zeichenketten als Indexwerte zugreifen. Was Du da also versuchst ist so was:

Code: Alles auswählen

In [1]: A = ['Bosch', 'Akustikfunktionen optimieren', 'Irgendwo', 42]

In [2]: A['firmenname']
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-740d1eba4de6> in <module>()
----> 1 A['firmenname']

TypeError: list indices must be integers, not str
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Sieht so aus als wäre dein `data_o` eine Liste und kein Dictionary.

Um ehrlich zu sein habe ich nicht viel Lust dein Projekt durchzusehen bei solch nichts sagenden/magischen Namen. `data_o`, `create_p`, `View_cl`, `path_s`, `lookup_o` etc.
the more they change the more they stay the same
breedi
User
Beiträge: 10
Registriert: Freitag 28. Oktober 2016, 18:50

@BlackJack Mein Data_o initialisiere ich in meiner database.py und lasse ihn die Werte aus meiner JSON-Datei ziehen. Nur ich weiß nicht wirklich wie ich vorgehen soll, ich könnte versuchen den Keywert für die Indizes durch explizite Typumwandlung in Integer umzuwandeln

Code: Alles auswählen

	
	#-------------------------------------------------------
	def __init__(self):
	#-------------------------------------------------------
	    self.data_o = None      #Liste für Firmenverzeichnisse
	    self.readData_p()       #Filestream für Data_o --> Source:Webteams.json
	    self.data_p = None      #Liste für Praxisphasen
	    self.readData_py()      #Filestream für Data_p --> Source:praxisphasenangebot.json

[codebox=pycon file=Unbenannt.txt]
# coding: utf-8

import os
import os.path
import codecs

import json

#----------------------------------------------------------
class Database_cl(object):
#----------------------------------------------------------
# da es hier nur darum geht, die Daten dauerhaft zu speichern,
# wird ein sehr einfacher Ansatz verwendet:


# - es können Daten zu genau 15 Teams gespeichert werden
# - je Team werden 2 Teilnehmer mit Namen, Vornamen und Matrikelnummer
# berücksichtigt
# - die Daten werden als eine JSON-Datei abgelegt

#-------------------------------------------------------
def __init__(self):
#-------------------------------------------------------
self.data_o = None #Liste für Firmenverzeichnisse
self.readData_p() #Filestream für Data_o --> Source:Webteams.json
self.data_p = None #Liste für Praxisphasen
self.readData_py() #Filestream für Data_p --> Source:praxisphasenangebot.json
#-------------------------------------------------------
def create_px(self, data_opl):
# Erstellt die Datenliste für die Firmenverzeichnisse ( Data_o)
# Überprüfung der Daten müsste ergänzt werden!

# 'freien' Platz suchen,
# falls vorhanden: belegen und Nummer des Platzes als Id zurückgeben

id_s = None
for loop_i in range(0,15):
if self.data_o[str(loop_i)][0] == '':
id_s = str(loop_i)
self.data_o[id_s] = data_opl
self.saveData_p()
break

return id_s

def create_py(self, data_op1):
# Erstellt die Datenliste für den praxisphasenmanager ( Data_p)
id_s = None
for loop_i in range(0,15):
if self.data_p[str(loop_i)][0] == '':
id_s = str(loop_i)
self.data_p[id_s] = data_op1
self.saveData_py()
break
return id_s

#-------------------------------------------------------
def read_px(self, id_spl = None):
# Readfunktion für die Firmenverzeichnisse
# hier zur Vereinfachung:
# Aufruf ohne id: alle Einträge liefern
data_o = None
if id_spl == None:
data_o = self.data_o
else:
if id_spl in self.data_o:
data_o = self.data_o[id_spl]

return data_o

def read_py(self, id_sp1 = None):
# Readfunktion für den Praxisphasenmanager
data_p = None
if id_sp1 == None:
data_p = self.data_p
else:
if id_sp1 in self.data_p:
data_p = self.data_p[id_sp1]

return data_p

#-------------------------------------------------------
def update_px(self, id_spl, data_opl):
# Updatefunktion für die Firmenverzeichnisse
# Überprüfung der Daten müsste ergänzt werden!
status_b = False
if id_spl in self.data_o:
self.data_o[id_spl] = data_opl
self.saveData_p()
status_b = True

return status_b

#-------------------------------------------------------
def update_py(self, id_spl, data_opl):
# Updatefunktion für die Praxisphasenmanager
status_b = False
if id_spl in self.data_p:
self.data_p[id_spl] = data_opl
self.saveData_py()
status_b = True

return status_b
#-------------------------------------------------------
def delete_px(self, id_spl):
#Löschfunktion für das Firmenverzeichnis
status_b = False
if id_spl in self.data_o:
# hier müssen Sie den Code ergänzen
# Löschen als Zurücksetzen auf die Default-Werte
self.data_o[id_spl] = self.getDefault_px()
self.saveData_p()
status_b = True
#Ihr Ergänzung
return status_b

def delete_py(self, id_sp1):
# Löschfunktion für den Praxisphasenmanager
status_b = False
if id_sp1 in self.data_p:
# Löschen als Zurücksetzen auf die Default-Werte
self.data_p[id_sp1] = self.getDefault_py()
self.saveData_py()
status_b = True

return status_b
#-------------------------------------------------------
def getDefault_px(self):
# Defeaultsetter für das Firmenverzeichnis
return['','','','','','']

def getDefault_py(self):
# Defaultsetter für die Praxisphasenangebot
return['','','','','','','','']

#-------------------------------------------------------
def readData_p(self):
#-------------------------------------------------------
try:
fp_o = codecs.open(os.path.join('data','webteams.json'),'r','utf-8')
except:
# Datei neu anlegen
self.data_o = {}
for loop_i in range(0,15):
self.data_o[str(loop_i)]=['','','','','','']
self.saveData_p()
else:
with fp_o:
self.data_o = json.load(fp_o)

return

#-------------------------------------------------------
def readData_py(self):
#-------------------------------------------------------

try:
fp_p = codecs.open(os.path.join('data','praxisphasenangebot.json'),'r','utf-8')
except:
self.data_p = {}
for loop_i in range(0,15):
self.data_p[str(loop_i)]=['','','','','','','','']
self.saveData_py()
else:
with fp_p:
self.data_p = json.load(fp_p)

return

#-------------------------------------------------------
def saveData_p(self):
#-------------------------------------------------------
with codecs.open(os.path.join('data','webteams.json'),'w','utf-8')as fp_o:
json.dump(self.data_o, fp_o)

def saveData_py(self):

with codecs.open(os.path.join('data','praxisphasenangebot.json'),'w','utf-8')as fp_p:
json.dump(self.data_p, fp_p)

# EOF[/code]

Ja, ich weiß ich müsste das allEs noch auslagern in verschiedene Dateien und ich werde mich bald mit dem Refactoring befassen. Ich wollte erstein letzten Bedingungen beenden, bevor ich mich damit befasse.
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@breedi: Dein Problem sind nicht zu wenig verschiedene Dateien, sondern zu viele. Außerdem zu viele ---- Zeilen und zu viele nichtssagende Postfixe. Was hat ein _px oder _o mit Firmenverzeichnis zu tun und was ein _py oder _p mit praxisphasenmanager?

Deine Datenstrukturen sind unnötig komplex. Statt alles auf einmal zu wollen, solltest Du Dir ersteinmal eine sinnvolle Datenstruktur überlegen und Funktionen schreiben, die auf diesen Daten arbeiten. Lass dieses ganz Web und Template-Zeugs erstmal weg, dazu ist es noch viel zu früh. Schreibe für den Zugriff Test-Routinen und arbeite viel mit print um zu lernen, was Python wie an welche Variablen bindet.
Welche Funktionen brauchst Du? Schreib einfach nur mal alle Funktionsnamen auf, so dass schon allein aus dem Namen klar wird, was die Funktion macht.
breedi
User
Beiträge: 10
Registriert: Freitag 28. Oktober 2016, 18:50

@Sirius3 Die Datenstrukturen habe ich mal angepasst und die Funktionsnamen lesender gemacht, sodass man damit etwas anfangen kann.
Ich weiß schon, wie ich das Programmieren muss. Ich konnte ja mit den Listen, Funktionsnamen etc etwas anfangen. Jetzt habe ich die Teile updatet und für euch lesbarer gemacht.

Es gint in diesem Beitrag ja nciht um die Funktionsnamen, sondern um das generieren der Templates mittels Mako.
BlackJack

@breedi: Das generieren der Templates mit Mako ist doch aber gar nicht das Problem gewesen. Du hast offensichtlich eine falsche Vorstellung davon wie die Daten aussehen die Du in das Template einfügen willst. Das gleiche Problem hättest Du ohne Mako auch gehabt wenn Du das statt in einer Schleife im Template in Python-Code mit einer Schleife versucht hättest. Da unterscheiden sich Mako und Python nicht.
breedi
User
Beiträge: 10
Registriert: Freitag 28. Oktober 2016, 18:50

@BlackJack Scheint der Fall zu sein. Deswegen bin ich auch hier und frage danach, weil ich gerade eine falsche Vorstellung davon habe, ich komme echt nicht weiter und ich weiß nicht was ihr meint.

@Update: Ich habe den Fehler gefunden. Ich arbeite schon mehrere Stunden dran und sollte jetzt auch damit aufhören, ich habe als Arrayindize ein String verwendet, natürlich konnte er den Wert nicht finden. Ich bin wohl was überarbeitet gewesen, dass ich soetwas triviales nicht erkannt habe....

Ich hätte ne Pause und frische Luft gebraucht :D
Antworten