Hat Python ein toString () -Äquivalent und kann ich ein db.Model-Element in String konvertieren?

87

Ich schreibe eine ToDo-Listen-App, um mir den Einstieg in Python zu erleichtern. Die App läuft auf GAE und ich speichere Aufgaben im Datenspeicher. Ich möchte ihnen alle Gegenstände zeigen, und sie allein. Das Problem ist, dass die App derzeit allen Benutzern alle Elemente anzeigt, sodass ich sehen kann, was Sie schreiben, und Sie sehen, was ich schreibe. Ich dachte, mein todo.author-Objekt in eine Zeichenfolge umzuwandeln und zu prüfen, ob es mit dem Namen des Benutzers übereinstimmt, wäre ein guter Anfang, aber ich kann nicht herausfinden, wie das geht.

Das habe ich in meiner main.py.

... 
user = users.get_current_user()

if user:
    nickname = user.nickname()
    todos = Todo.all()
    template_values = {'nickname':nickname, 'todos':todos}
...

def post(self):

    todo = Todo()
    todo.author = users.get_current_user()
    todo.item = self.request.get("item")
    todo.completed = False

    todo.put()      
    self.redirect('/')

In meiner index.html hatte ich dies ursprünglich:

<input type="text" name="item" class="form-prop" placeholder="What needs to be done?" required/>
...
 <ul>
{% for todo in todos %}
  <input type="checkbox"> {{todo.item}} <hr />
{% endfor %}
</ul>

Ich möchte Elemente jedoch nur dem Benutzer anzeigen, der sie erstellt hat. Ich dachte daran, es zu versuchen

{% for todo in todos %}
    {% ifequal todo.author nickname %}
  <input type="checkbox"> {{todo.item}} <hr />
    {% endifequal %}
{% endfor %}

umsonst. Die Liste wird leer angezeigt. Ich nahm an, dass es daran liegt, dass todo.author keine Zeichenfolge ist. Kann ich den Wert als Zeichenfolge auslesen oder das Objekt in Zeichenfolge umwandeln?

Vielen Dank!

Edit: Hier ist meine Todo-Klasse

class Todo(db.Model):
author = db.UserProperty()
item = db.StringProperty()
completed = db.BooleanProperty()
date = db.DateTimeProperty(auto_now_add=True)

Wird sich das Ändern meines Autors in eine StringProperty negativ auswirken? Vielleicht kann ich ganz auf das Casting verzichten.

Amru E.
quelle

Antworten:

92

In Python, das str()Verfahren ist ähnlich dem toString()Verfahren in anderen Sprachen. Es wird aufgerufen, das Objekt zu übergeben, um es als Parameter in eine Zeichenfolge zu konvertieren. Intern ruft es die__str__() Methode des Parameterobjekts auf, um seine Zeichenfolgendarstellung abzurufen.

In diesem Fall vergleichen Sie jedoch einen UserPropertyAutor aus der Datenbank, der vom Typ ist, users.Usermit der Kurznamenzeichenfolge. Sie möchten nicknamestattdessen die Eigenschaft des Autors mit der todo.author.nicknamein Ihrer Vorlage vergleichen.

Jeff Lockhart
quelle
Danke für die Antwort. Beim Versuch von str (todo.author) in der Vorlage wird folgende Fehlermeldung angezeigt: Irgendwelche TemplateSyntaxError: Could not parse the remainder: '(todo.author)' from 'str(todo.author)'Ideen?
Amru E.
1
Versuchen Sie, solche Anführungszeichen zu setzen 'str(todo.author)'. Ich habe keine Erfahrung mit Django-Vorlagen, aber es scheint, dass der Analysemechanismus in Klammern nach dem strFunktionsnamen hängen bleibt . Oder Sie erhalten lieber die Zeichenfolgeeigenschaft des Autors, möglicherweise so etwas todo.author.nickname, ohne dass der str()Aufruf erforderlich ist .
Jeff Lockhart
Ich habe es endlich geschafft! Ich habe in meiner if-Anweisung todo.author.nickname verwendet und überprüft, ob dieser Wert mit dem Spitznamen des aktuellen Benutzers übereinstimmt. Bitte bearbeiten Sie Ihre Antwort so, dass ich sie akzeptieren kann.
Amru E.
35

In Python können wir die __str__()Methode verwenden.

Wir können es in unserer Klasse folgendermaßen überschreiben:

class User: 

    firstName = ''
    lastName = ''
    ...

    def __str__(self):
        return self.firstName + " " + self.lastName

und beim Laufen

print(user)

Es ruft die Funktion auf __str__(self) und gibt den Vor- und Nachnamen aus

Amirouche Zeggagh
quelle
6

str() ist das Äquivalent.

Sie sollten jedoch Ihre Abfrage filtern. Im Moment ist Ihre Anfrage all()Todo's.

todos = Todo.all().filter('author = ', users.get_current_user().nickname()) 

oder

todos = Todo.all().filter('author = ', users.get_current_user())

abhängig davon, was Sie als Autor im Todo-Modell definieren. A StringPropertyoder UserProperty.

Hinweis nicknameist eine Methode. Sie übergeben die Methode und nicht das Ergebnis in Vorlagenwerten.

Tim Hoffman
quelle
Danke für die Antwort! Ich werde jetzt versuchen, den Filter zu implementieren. Ich bin allerdings etwas verwirrt über den Spitznamen. Ich habe schon früher damit herumgespielt und konnte es wie jede andere Zeichenfolge manipulieren und durch den Vorlagenwert senden. Vermisse ich etwas Oh und Autor ist eine UserProperty. Ich werde das zu meiner ursprünglichen Frage hinzufügen.
Amru E.
Ich verwende keine Django-Vorlagen, daher weiß ich nicht, was sie tun werden. Einige Templating-Systeme rufen automatisch Callables (Spitzname ()) auf
Tim Hoffman
Haben Sie etwas dagegen, kurz zu erklären, was der Filter tun würde? Ich bin nicht sicher, was die eigentliche Funktion meiner todos = Todo.all () ist.
Amru E.
Wie Sie dem Beispielcode entnehmen können, ist filter ein Abfrageargument, insbesondere author property = some value. Sie sollten wirklich einige Zeit damit verbringen, die Dokumente zu lesen. Das spart Ihnen viel Zeit. developer.google.com/appengine/docs/python/datastore spricht über den Datenspeicher und darüber, wie Daten abgerufen / abgelegt und abgefragt werden.
Tim Hoffman
2

Sie sollten die __unicode__Methode in Ihrem Modell definieren, und die Vorlage ruft sie automatisch auf, wenn Sie auf die Instanz verweisen.

Daniel Roseman
quelle
2

In der Funktion post ():

todo.author = users.get_current_user()

Um str (todo.author) zu erhalten, benötigen Sie str (users.get_current_user ()). Was wird von der Funktion get_current_user () zurückgegeben?

Wenn es sich um ein Objekt handelt, prüfen Sie, ob es eine str () "- Funktion enthält.

Ich denke, der Fehler liegt dort.

Sinhayash
quelle
users.get_current_user () gibt ein Benutzerobjekt mit dem Spitznamen () zurück, um dem Benutzer einen lesbaren Namen zu geben. Ich hatte Probleme, den Spitznamen richtig zu finden, aber ich habe es herausgefunden. Vielen Dank!
Amru E.