2016-04-18 7 views
1

Ich habe eine Liste von Benutzer-IDs an meine API gesendet werden:Python, wenn eine Liste keine Liste ist? Liste Objekt hat kein Attribut aufgeteilt

Users = ['x1','x2'] 

create-Methode In meinem Serializer ich versuche, über sie iterieren:

users = validated_data.get('users', None) 
    for user in users: 
     print(user) 
     print("===") 

Der Ausgang I Empfangen ist:

Es statt Iterieren über die Liste, gibt es als eine Zeile aus! Dies deutet darauf hin, dass es sich nicht um eine Liste handelt, sondern um eine Zeichenfolge, also überprüfte ich die type(users), die ein Leerzeichen, d. H. Keinen Typ, ergab.

Also habe ich versucht Splitting Benutzer bis users.split() Dann bekomme ich einen Widerspruch“!

Liste Objekt kein Attribut geteilt hat‘

Was ist hier falsch, verwirrt?

+1

Verwenden Sie Django? Wo ist valided_data definiert? Das gibt einen Hinweis darauf, was der Rückgabetyp dieser Methode ist. – Moshe

+2

Es stimmt, Listen haben keine Aufteilung. Nur Strings tun. – BallpointBen

+0

Welchen Rahmen verwenden Sie? Sie sprechen über ListSerializer ... ist das Django-Rest-Framework? – SpoonMeiser

Antwort

1

Andere haben darauf hingewiesen, dass Sie scheinen eine Liste zu haben, eine einzelne Zeichenfolge enthält, ['x1, x2'].

Ich habe mir die Django REST Framework Interna angesehen und es gibt definitiv eine Liste zurück.

ListField erbt von Field, die einige Methoden definiert, einschließlich run_validation, to_internal_value und to_representation.

Zwei dieser Methoden sind abstrakt, und eine davon, run_validation, ruft die Validierung tatsächlich auf, indem sie self.to_internal_value(data) aufruft.

Um zu sehen, was der Validator macht, müssen wir uns die Implementierung von to_internal_value von ListField anschauen.

Der Kommentar innerhalb von to_internal_value sagt dies:

""" 
    List of dicts of native values <- List of dicts of primitive datatypes. 
""" 

Dann überprüft er für ungültige Eingabetypen und schließlich ruft run_validation.

Laut meiner IDE gibt es 5 Implementierungen von run_validation in Django REST Framework. Der relevanteste ist wahrscheinlich ListSerializer.

5 implementations of run_validation

Die Kommentare über ListSerializer sagen uns, dass wir wahrscheinlich an der richtigen Stelle sind:

# There's some replication of `ListField` here, 
# but that's probably better than obfuscating the call hierarchy. 

Die ListSerializer Klasse validates each item (source) und dann auf eine Liste anhängt es genannt ret. Also sollten wir eine Liste zurückgeben.

Das ungelöste Teil des Puzzles ist hier, was Ihre Eingabe ist, verursacht die Ausgabe falsch sein, aber durch die Aufrufliste verfolgen, scheint der Code wie vorgesehen funktioniert.

EDIT:

Könnte es sein, dass to_representation Ihre Liste ist Abflachung, weil es es ist ein Wörterbuch denkt?

+0

Vielen Dank für diese @Moche erscheint es, dass '' to_representation'' und '' to_internal_value'' war das Problem! es machte es zu einer Zeichenkette, wenn es mit multipart/formdata verwendet wurde! :) – Prometheus

+0

Froh, zu helfen. Es könnte sich lohnen, bei der html-Handhabung in diesen Methoden herumzustochern, denn das scheint dort der Sonderfall zu sein. – Moshe

+0

Können Sie mir sagen, welche Versionen von Python und DRF Sie verwenden? – Moshe

1

Es als users a ist aussieht Liste mit einem einzigen Artikel x1,x2:

>>> users = ['x1,x2'] 
>>> for user in users: 
...  print(user) 
...  print("===") 
... 
x1,x2 
=== 
+0

Ich benutze '' serializers.ListField() '' um die Daten ohne Validierungsfehler zu posten und die Daten sind '' ['x1', 'x2'] '', ist das keine Liste? Warum sollte '' (Benutzer) '' auch ein Leerzeichen geben? – Prometheus

+0

@Spaceships ja, komisches Format. Könnten Sie zeigen, was "valided_data" ist? – alecxe

+0

valided_data ist der Standard DRF hier ist die Ausgabe '' {'Organisation': 1, 'Benutzer': ['1,2'], 'Nachricht': 'Test', 'Datetime': datetime.datetime (2016, 4 , 29, 0, 0, tzinfo = )} '' – Prometheus

2

Es scheint, dass die Nutzer eine Liste, die wie folgt aussieht : ['x1,x2']. Statt dessen, was Sie erwartet: ['x1','x2']

Sie können ast.literal_eval verwenden, um zunächst eine Liste zu machen, oder Sie können aufgeteilt nur, dass ein Element:

users = ['x1,x2'] 
for user in users[0].split(','): 
    print(user) 
    print('===') 

Ausgang:

>>> users = ['x1,x2'] 
>>> for user in users[0].split(','): 
... print(user) 
... print('===') 


x1 
=== 
x2 
=== 

A pro Ihren Kommentar :

Ausgabe:

1 
=== 
2 
=== 

Für users = ['[x1,x1]']:

users = ['[x1,x1]'] 
users = users[0][1:-1] 

for user in users.split(','): 
    print(user) 
    print('===') 
+0

Auch mit '' [1,2] '' Ich bekomme immer noch '' [1,2] '' statt 1 === 2 === – Prometheus

+0

Ich bin nicht sicher, warum ich das tun muss, sollte es sei einfach eine Standardliste. http://www.django-rest-framework.org/api-guide/fields/#listfield – Prometheus

+0

@SpaceShips Sorry, ich habe vergessen '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''Sollte jetzt funktionieren –

Verwandte Themen