¿Python tiene un equivalente toString () y puedo convertir un elemento db.Model en String?

87

Estoy escribiendo una aplicación de lista de tareas pendientes para ayudarme a comenzar con Python. La aplicación se ejecuta en GAE y estoy almacenando elementos de tareas pendientes en el almacén de datos. Quiero mostrarles los artículos de todos, y solo a ellos. El problema es que la aplicación actualmente muestra todos los elementos a todos los usuarios, así que puedo ver lo que escribes y tú ves lo que escribo. Pensé que lanzar mi objeto todo.author a una cadena y ver si coincide con el nombre del usuario sería un buen comienzo, pero no sé cómo hacerlo.

Esto es lo que tengo en mi 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('/')

En mi index.html tenía esto originalmente:

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

pero me gustaría mostrar elementos solo al usuario que los creó. Pensé en intentarlo

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

en vano. La lista aparece en blanco. Supuse que es porque todo.author no es una cadena. ¿Puedo leer el valor como una cadena o puedo convertir el objeto en String?

¡Gracias!

Editar: Aquí está mi clase de Todo

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

¿Cambiar mi autor a StringProperty afectará algo negativamente? Quizás pueda renunciar al casting por completo.

Amru E.
fuente

Respuestas:

92

En Python, el str()método es similar al toString()método en otros lenguajes. Se llama pasar el objeto para convertirlo en una cadena como parámetro. Internamente, llama al __str__()método del objeto de parámetro para obtener su representación de cadena.

En este caso, sin embargo, está comparando un UserPropertyautor de la base de datos, que es del tipo users.Usercon la cadena de apodo. En su lugar, querrá comparar la nicknamepropiedad del autor con la todo.author.nicknamede su plantilla.

Jeff Lockhart
fuente
Gracias por la respuesta. Recibo el siguiente error al intentar str (todo.author) en la plantilla: ¿ TemplateSyntaxError: Could not parse the remainder: '(todo.author)' from 'str(todo.author)'alguna idea?
Amru E.
1
Intente poner comillas 'str(todo.author)'como tal. No tengo experiencia con las plantillas de Django, pero parece que su mecanismo de análisis se bloquea en el paréntesis después del strnombre de la función. O puede que prefiera obtener la propiedad de cadena del autor, posiblemente algo así todo.author.nickname, sin la necesidad de la str()llamada.
Jeff Lockhart
¡Finalmente lo hice funcionar! Usé todo.author.nickname en mi declaración if y verifiqué si ese valor coincidía con el apodo del usuario actual. Edite su respuesta para incluirla para que pueda aceptarla.
Amru E.
35

En Python podemos usar el __str__()método.

Podemos anularlo en nuestra clase de esta manera:

class User: 

    firstName = ''
    lastName = ''
    ...

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

y al correr

print(user)

llamará a la función __str__(self) e imprimirá el nombre y apellido

Amirouche Zeggagh
fuente
6

str() es el equivalente.

Sin embargo, debería filtrar su consulta. Por el momento tu consulta es de all()Todo.

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

o

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

dependiendo de lo que esté definiendo autor como en el modelo Todo. A StringPropertyo UserProperty.

La nota nicknamees un método. Está pasando el método y no el resultado en valores de plantilla.

Tim Hoffman
fuente
¡Gracias por responder! Seguiré adelante e intentaré implementar el filtro ahora. Aunque estoy un poco confundido sobre el apodo. He jugado con él antes y pude manipularlo como cualquier otra cadena y enviarlo a través del valor de la plantilla sin problemas. ¿Me estoy perdiendo de algo? Ah, y el autor es una propiedad de usuario. Agregaré eso a mi pregunta original.
Amru E.
No uso plantillas de django, así que no sé qué harán. Algunos sistemas de plantillas llamarán automáticamente a las personas que llaman (apodo ())
Tim Hoffman
¿Le importaría explicar brevemente qué haría el filtro? No estoy seguro de cuál es la función real de mi todos = Todo.all ().
Amru E.
Como puede ver en el código de ejemplo, el filtro es un argumento de consulta, específicamente la propiedad del autor = algún valor. Realmente debería dedicar algo de tiempo a leer los documentos, le ahorrará mucho tiempo. developers.google.com/appengine/docs/python/datastore habla sobre el almacén de datos y cómo obtener / colocar y consultar datos.
Tim Hoffman
2

Debe definir el __unicode__método en su modelo y la plantilla lo llamará automáticamente cuando haga referencia a la instancia.

Daniel Roseman
fuente
2

En función post ():

todo.author = users.get_current_user()

Entonces, para obtener str (todo.author), necesitas str (users.get_current_user ()). ¿Qué devuelve la función get_current_user ()?

Si es un objeto, verifique si contiene una función str () "?

Creo que el error está ahí.

sinhayash
fuente
users.get_current_user () devuelve un objeto Usuario que tiene un apodo () para proporcionar un nombre legible para el usuario. Estaba teniendo problemas para obtener el apodo correctamente, pero lo descubrí. ¡Gracias!
Amru E.