Python a-t-il un équivalent toString () et puis-je convertir un élément db.Model en String?

87

J'écris une application de liste ToDo pour m'aider à démarrer avec Python. L'application fonctionne sur GAE et je stocke des éléments à faire dans le magasin de données. Je veux leur montrer les objets de tout le monde, et eux seuls. Le problème est que l'application affiche actuellement tous les éléments à tous les utilisateurs, afin que je puisse voir ce que vous écrivez et que vous voyez ce que j'écris. Je pensais que convertir mon objet todo.author en une chaîne et voir s'il correspond au nom de l'utilisateur serait un bon début, mais je ne peux pas comprendre comment faire cela.

C'est ce que j'ai dans mon 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('/')

Dans mon index.html j'avais ceci à l'origine:

<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>

mais j'aimerais afficher les éléments uniquement à l'utilisateur qui les a créés. J'ai pensé essayer

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

en vain. La liste est vide. J'ai supposé que c'était parce que todo.author n'est pas une chaîne. Puis-je lire la valeur sous forme de chaîne ou puis-je convertir l'objet en chaîne?

Merci!

Edit: Voici ma classe Todo

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

Le fait de changer mon auteur en StringProperty aura-t-il un effet négatif? Peut-être que je peux renoncer complètement au casting.

Amru E.
la source

Réponses:

92

En python, la str()méthode est similaire à la toString()méthode dans d'autres langages. Cela s'appelle passer l'objet à convertir en chaîne en tant que paramètre. En interne, il appelle la __str__()méthode de l'objet paramètre pour obtenir sa représentation sous forme de chaîne.

Dans ce cas, cependant, vous comparez un UserPropertyauteur de la base de données, qui est de type users.Useravec la chaîne de pseudonyme. Vous voudrez nicknameplutôt comparer la propriété de l'auteur avec todo.author.nicknamedans votre modèle.

Jeff Lockhart
la source
Merci d'avoir répondu. J'obtiens l'erreur suivante en essayant str (todo.author) dans le modèle: TemplateSyntaxError: Could not parse the remainder: '(todo.author)' from 'str(todo.author)'des idées?
Amru E.
1
Essayez de mettre des citations 'str(todo.author)'comme ça. Je ne suis pas expérimenté avec les modèles Django, mais il semble que son mécanisme d'analyse se bloque à la parenthèse après le strnom de la fonction. Ou vous pouvez plutôt obtenir la propriété string de l'auteur, éventuellement quelque chose comme todo.author.nickname, sans avoir besoin de l' str()appel.
Jeff Lockhart
J'ai finalement réussi à le faire fonctionner! J'ai utilisé todo.author.nickname dans mon instruction if et j'ai vérifié si cette valeur correspondait au surnom de l'utilisateur actuel. Veuillez modifier votre réponse pour l'inclure afin que je puisse l'accepter.
Amru E.
35

En Python, nous pouvons utiliser la __str__()méthode.

Nous pouvons le remplacer dans notre classe comme ceci:

class User: 

    firstName = ''
    lastName = ''
    ...

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

et en courant

print(user)

il appellera la fonction __str__(self) et affichera le firstName et le lastName

Amirouche Zeggagh
la source
6

str() est l'équivalent.

Cependant, vous devriez filtrer votre requête. Pour le moment, votre requête est celle de all()Todo.

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

ou

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

selon ce que vous définissez l'auteur comme dans le modèle Todo. A StringPropertyou UserProperty.

La note nicknameest une méthode. Vous transmettez la méthode et non le résultat en valeurs de modèle.

Tim Hoffman
la source
Merci pour votre réponse! Je vais aller de l'avant et essayer de mettre en œuvre le filtre maintenant. Je suis un peu confus à propos du surnom. J'ai déjà joué avec et j'ai pu la manipuler comme n'importe quelle autre chaîne et l'envoyer à travers la valeur du modèle très bien. Est-ce que je manque quelque chose? Oh et l'auteur est une propriété utilisateur. J'ajouterai cela à ma question initiale.
Amru E.
Je n'utilise pas de modèles django, donc je ne sais pas ce qu'ils vont faire. Certains systèmes de modèles appelleront automatiquement les callables (pseudo ())
Tim Hoffman
Cela vous dérange-t-il d'expliquer brièvement ce que ferait le filtre? Je ne suis pas sûr de la fonction réelle de mes todos = Todo.all ().
Amru E.
Comme vous pouvez le voir dans l'exemple de code, filter est un argument de requête, en particulier author property = une valeur. Vous devriez vraiment passer du temps à lire les documents, cela vous fera gagner beaucoup de temps. developers.google.com/appengine/docs/python/datastore parle de la datastore et comment obtenir / mettre et les données de la requête.
Tim Hoffman
2

Vous devez définir la __unicode__méthode sur votre modèle et le modèle l'appellera automatiquement lorsque vous référencerez l'instance.

Daniel Roseman
la source
2

Dans la fonction post ():

todo.author = users.get_current_user()

Donc, pour obtenir str (todo.author), vous avez besoin de str (users.get_current_user ()). Que renvoie la fonction get_current_user ()?

S'il s'agit d'un objet, vérifiez s'il contient une fonction str () "?

Je pense que l'erreur est là.

sinhayash
la source
users.get_current_user () retourne un objet User qui a nickname () pour fournir un nom lisible à l'utilisateur. J'avais du mal à obtenir le surnom correctement, mais je l'ai compris. Merci!
Amru E.