Initialisierung eines QueryDict.fromkeys

9

Wir können eine neue dict-Instanz aus einer Schlüsselliste initialisieren:

%Vor%

Und ein Querydict ist ein Diktat, also sollte das funktionieren, oder?

%Vor%

Natürlich kann ich etwas lahmen wie QueryDict('spam&spam&potato') , aber meine Frage: Ist die .fromkeys Methode überhaupt brauchbar oder komplett kaputt?

Wenn Ersteres, wie benutzt du es? Wenn letzteres, warum wurde es nicht explizit in der Unterklasse deaktiviert?

    
wim 10.11.2015, 22:06
quelle

3 Antworten

1

tl; dr QueryDict.fromkeys wird anfangen zu arbeiten die Django 1.11 Veröffentlichung.

Auf der PyCon 2016 hatte ich die Gelegenheit, mit einigen Django-Kernentwicklern zu sprechen, wir stimmten darin überein, dass die ererbte Methode gebrochen ist und die Liskov-Substitution verletzt Prinzip . Bei einem der Sprints konnte ich dieses Problem lösen und die QueryDict-Klasse patchen.

Hier ist das relevante Commit und Problem , das Update ist jetzt in Master und bereits in der Dokumentation . Ich habe eine ähnliche Implementierung wie beim ersten Vorschlag von hynekcer verwendet.

    
wim 14.06.2016, 16:27
quelle
1

Das Problem hängt auch von der Django-Version ab. Sie verwenden Django 1.7.x oder älter, das den Positionsparameter query_string für QueryDict benötigt. Es ist in Django 1.8 behoben, wo dieser Parameter optional ist.

Das zweite Problem ist, dass QueryDict standardmäßig eine unveränderliche Instanz erstellt und es keine Möglichkeit gibt, mutable=True bis fromkeys zu übergeben. Die Schlüssel können nicht unveränderlich hinzugefügt werden und die Methode schlägt auch in Django 1.8 fehl.

Es kann auf diese Weise behoben werden:

%Vor%

Es wird komplizierter implementiert, um wiederholte Schlüssel wiederzugeben. Der Standardwert ist die leere Zeichenfolge, da es nicht sinnvoll ist, sie in die Zeichenfolge "None" wie 'potato=None&spam=None&spam=None' by urlencode() method zu konvertieren. Das Standardergebnis QueryDict sollte mit QueryDict('potato&spam&spam') identisch sein.

Die vorgestellte Lösung ist so seltsam, dass raise NotImplemented() eine einfachere "Implementierung" wäre. (EDIT: Ich erwarte nicht, dass irgendetwas mehr nützlich genug ist, um zu Django Code-Basis akzeptiert zu werden) Allerdings muss ich dir zustimmen, es ist ein Bug mit mysteriösen Nachrichten. Nicht implementierte Funktionalitäten sind normalerweise undokumentiert, wenn sie keinen Warnhinweis benötigen, weil sie endlos viele gefunden werden können.

Eine andere Lösung wäre, nur __init__ zu ändern:

%Vor%

weil unveränderliche QueryDict-Instanzen häufig unpraktisch sind und sogar die Hälfte der internen Verwendung in Django mit veränderbaren QueryDict-Instanzen erfolgt.

    
hynekcer 14.11.2015 04:10
quelle
0

Obwohl QueryDict ein Dict ist, besteht das Hauptproblem darin, dass es standardmäßig ein unveränderliches Dict ist. Außerdem erhältst du keine sehr gute Fehlermeldung (ich benutze Django 1.8+ und bekomme eine klarere Nachricht 'Diese QueryDict-Instanz ist unveränderlich').

Wenn Sie also Ihre eigene QueryDict -Instanz erstellen, können Sie sie als veränderbar deklarieren:

%Vor%

Wenn Sie eine bereits vorhandene QueryDict haben, können Sie eine Kopie davon erstellen, die automatisch veränderbar macht:

%Vor%

Zusammenfassend kann gesagt werden, dass ein sehr subtiler Fehler beim Aufruf von fromkeys() auf einem QueryDict auftritt. Aber Sie können mit der update() -Methode darüber hinwegkommen und erkennen, dass Sie die QueryDict veränderbar machen müssen.

    
D Rubio 18.11.2015 16:54
quelle

Tags und Links