Python ha un equivalente toString () e posso convertire un elemento db.Model in String?


90

Sto scrivendo un'app ToDo list per iniziare con Python. L'app è in esecuzione su GAE e sto archiviando elementi todo in Data Store. Voglio mostrare gli articoli di tutti a loro e solo loro. Il problema è che l'app attualmente mostra tutti gli elementi a tutti gli utenti, quindi posso vedere cosa scrivi e tu vedi cosa scrivo. Ho pensato che lanciare il mio oggetto todo.author su una stringa e vedere se corrisponde al nome dell'utente sarebbe stato un buon inizio, ma non riesco a capire come farlo.

Questo è quello che ho nel mio 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('/')

Nel mio index.html avevo questo originariamente:

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

ma vorrei mostrare gli elementi solo all'utente che li ha creati. Ho pensato di provare

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

inutilmente. L'elenco risulta vuoto. Ho pensato che fosse perché todo.author non è una stringa. Posso leggere il valore come una stringa o posso eseguire il cast dell'oggetto su String?

Grazie!

Modifica: ecco la mia classe di cose da fare

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

Cambiare il mio autore in StringProperty avrà un effetto negativo? Forse posso rinunciare del tutto al casting.

Risposte:


96

In Python, il str()metodo è simile al toString()metodo in altri linguaggi. Viene chiamato passaggio dell'oggetto da convertire in una stringa come parametro. Internamente chiama il __str__()metodo dell'oggetto parametro per ottenere la sua rappresentazione di stringa.

In questo caso, tuttavia, stai confrontando un UserPropertyautore dal database, che è di tipo users.Usercon la stringa del nickname. Dovrai invece confrontare la nicknameproprietà dell'autore con quella todo.author.nicknamedel tuo modello.


Grazie per la risposta. Ricevo il seguente errore quando provo str (todo.author) nel modello: TemplateSyntaxError: Could not parse the remainder: '(todo.author)' from 'str(todo.author)'qualche idea?
Amru E.

1
Prova a mettere le virgolette in questo 'str(todo.author)'modo. Non ho esperienza con i modelli Django, ma sembra che il suo meccanismo di analisi si blocchi tra parentesi dopo il strnome della funzione. Oppure potresti piuttosto ottenere la proprietà string dell'autore, possibilmente qualcosa di simile todo.author.nickname, senza la necessità della str()chiamata.
Jeff Lockhart,

Finalmente sono riuscito a farlo funzionare! Ho usato todo.author.nickname nella mia istruzione if e ho controllato se quel valore corrispondeva al nickname dell'utente corrente. Modifica la tua risposta per includerla in modo che possa accettarla.
Amru E.

37

In Python possiamo usare il __str__()metodo.

Possiamo sovrascriverlo nella nostra classe in questo modo:

class User: 

    firstName = ''
    lastName = ''
    ...

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

e durante la corsa

print(user)

chiamerà la funzione __str__(self) e stamperà firstName e lastName


6

str() è l'equivalente.

Tuttavia dovresti filtrare la tua query. Al momento la tua domanda è di all()Todo.

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

o

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

a seconda di ciò che stai definendo autore come nel modello Todo. A StringPropertyo UserProperty.

La nota nicknameè un metodo. Stai passando il metodo e non il risultato nei valori del modello.


Grazie per la risposta! Vado avanti e cercherò di implementare il filtro ora. Però sono un po 'confuso riguardo al soprannome. Ci ho già giocato in passato e sono stato in grado di manipolarlo come qualsiasi altra stringa e inviarlo correttamente attraverso il valore del modello. Mi sto perdendo qualcosa? Oh, e l'autore è una proprietà utente. Lo aggiungerò alla mia domanda originale.
Amru E.

Non uso i template django, quindi non so cosa faranno. Alcuni sistemi di template chiameranno automaticamente callables (nickname ())
Tim Hoffman

Ti dispiace spiegare brevemente cosa farebbe il filtro? Non sono sicuro di quale sia la funzione effettiva del mio todos = Todo.all ().
Amru E.

Come puoi vedere dal codice exmaple, il filtro è un argomento della query, in particolare la proprietà dell'autore = un valore. Dovresti davvero passare un po 'di tempo a leggere i documenti, ti farà risparmiare un sacco di tempo. developer.google.com/appengine/docs/python/datastore parla del datastore e di come ottenere / inserire ed eseguire query sui dati.
Tim Hoffman

2

È necessario definire il __unicode__metodo sul modello e il modello lo chiamerà automaticamente quando si fa riferimento all'istanza.


2

Nella funzione post ():

todo.author = users.get_current_user()

Quindi, per ottenere str (todo.author), è necessario str (users.get_current_user ()). Cosa viene restituito dalla funzione get_current_user ()?

Se è un oggetto, controlla se contiene una funzione str () "?

Penso che l'errore sia lì.


users.get_current_user () restituisce un oggetto Utente che ha nickname () per fornire un nome leggibile per l'utente. Ho avuto problemi a ottenere correttamente il soprannome, ma l'ho capito. Grazie!
Amru E.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.