import collections
data = [
{'firstname': 'John', 'lastname': 'Smith'},
{'firstname': 'Samantha', 'lastname': 'Smith'},
{'firstname': 'shawn', 'lastname': 'Spencer'},
]
new_data = collections.defaultdict(list)
for d in data:
new_data[d['lastname']].append(d['firstname'])
print new_data
Hier ist die Ausgabe:
defaultdict(<type 'list'>, {'Smith': ['John', 'Samantha'], 'Spencer': ['shawn']})
und hier ist die Vorlage:
{% for lastname, firstname in data.items %}
<h1> {{ lastname }} </h1>
<p> {{ firstname|join:", " }} </p>
{% endfor %}
Aber die Schleife in meiner Vorlage funktioniert nicht. Es zeigt sich nichts. Es gibt mir nicht einmal einen Fehler. Wie kann ich das beheben? Es soll den Nachnamen zusammen mit dem Vornamen anzeigen, ungefähr so:
<h1> Smith </h1>
<p> John, Samantha </p>
<h1> Spencer </h1>
<p> shawn </p>
Antworten:
Versuchen:
dict(new_data)
und in Python 2 ist es besser,
iteritems
anstatt zu verwendenitems
:)quelle
Sie können das Kopieren in ein neues Diktat vermeiden, indem Sie die Standardfunktion von defaultdict deaktivieren, sobald Sie neue Werte eingefügt haben:
new_data.default_factory = None
Erläuterung
Das Algorithmus zur variablen Auflösung von Vorlagen in Django versucht
new_data.items
alsnew_data['items']
erstes aufzulösen , der bei Verwendung von defaultdict (Liste) in eine leere Liste aufgelöst wird .Um die Standardeinstellung für eine leere Liste zu deaktivieren und Django auszuschalten und
new_data['items']
die Auflösungsversuche bis zum Aufruf fortzusetzen, kannnew_data.items()
das Attribut default_factory von defaultdict auf None festgelegt werden .quelle
Da das "Problem" noch Jahre später besteht und der Funktionsweise von Django-Vorlagen eigen ist, schreibe ich lieber eine neue Antwort mit den vollständigen Details, warum dieses Verhalten unverändert bleibt.
So beheben Sie den Fehler
Zunächst besteht die Lösung darin, das
defaultdict
in adict
umzuwandeln, bevor es an den Vorlagenkontext übergeben wird:context = { 'data': dict(new_data) }
Sie sollten nicht verwenden
defaultdict
in Django Objekte im Vorlagenkontext verwenden.Aber wieso?
Der Grund für diesen "Fehler" wird in der folgenden Django-Ausgabe Nr. 16335 beschrieben :
... und aus den Dokumenten :
Wenn Django Ihren Vorlagenausdruck auflöst , wird es zuerst versucht
data['items']
. ABER dies ist ein gültiger Ausdruck, der automatisch einen neuen Eintragitems
in Ihrem Standarddikt erstelltdata
, mit einer leeren Liste initialisiert (im Fall des ursprünglichen Autors) und die erstellte Liste zurückgibt (leer).Die beabsichtigte Aktion wäre, die Methode
items
ohne Argumente der Instanz aufzurufendata
(kurz :)data.items()
, aber da diesdata['items']
ein gültiger Ausdruck war, stoppt Django dort und erhält die gerade erstellte leere Liste.Wenn Sie den gleichen Code versuchen, aber mit
data = defaultdict(int)
, erhalten Sie einenTypeError: 'int' object is not iterable
, da Django nicht in der Lage ist, über den Wert "0" zu iterieren, der durch die Erstellung des neuen Eintrags von zurückgegeben wirddefaultdict
.quelle