O Python tem um equivalente toString () e posso converter um elemento db.Model em String?

87

Estou escrevendo um aplicativo de lista de tarefas para me ajudar a começar a usar o Python. O aplicativo está sendo executado no GAE e estou armazenando itens de tarefas no armazenamento de dados. Eu quero exibir os itens de todos para eles, e apenas eles. O problema é que o aplicativo atualmente exibe todos os itens para todos os usuários, então eu posso ver o que você escreve e você vê o que escrevo. Achei que lançar meu objeto todo.author em uma string e ver se ele corresponde ao nome do usuário seria um bom começo, mas não consigo descobrir como fazer isso.

Isso é o que tenho em meu 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('/')

No meu index.html eu tinha 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>

mas gostaria de exibir os itens apenas para o usuário que os criou. Pensei em tentar

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

sem sucesso. A lista fica em branco. Presumi que fosse porque todo.author não é uma string. Posso ler o valor como uma string ou posso converter o objeto em String?

Obrigado!

Editar: aqui está minha classe de tarefas

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

Mudar meu autor para StringProperty afetará negativamente? Talvez eu possa renunciar totalmente ao elenco.

Amru E.
fonte

Respostas:

92

Em python, o str()método é semelhante ao toString()método em outras linguagens. É chamado de passar o objeto a ser convertido em string como parâmetro. Internamente, ele chama o __str__()método do objeto de parâmetro para obter sua representação de string.

Neste caso, entretanto, você está comparando um UserPropertyautor do banco de dados, que é do tipo users.Usercom a string do apelido. Você vai querer comparar a nicknamepropriedade do autor em vez de todo.author.nicknameem seu modelo.

Jeff Lockhart
fonte
Obrigado pela resposta. Estou recebendo o seguinte erro ao tentar str (todo.author) no modelo: TemplateSyntaxError: Could not parse the remainder: '(todo.author)' from 'str(todo.author)'alguma ideia?
Amru E.
1
Tente colocar aspas 'str(todo.author)'assim. Não tenho experiência com modelos Django, mas parece que seu mecanismo de análise está travando entre parênteses após o strnome da função. Ou você pode preferir obter a propriedade string do autor, possivelmente algo como todo.author.nickname, sem a necessidade da str()chamada.
Jeff Lockhart
Eu finalmente consegui que isso funcione! Usei todo.author.nickname em minha instrução if e verifiquei se esse valor correspondia ao apelido do usuário atual. Edite sua resposta para incluí-la para que eu possa aceitá-la.
Amru E.
35

Em Python, podemos usar o __str__()método.

Podemos substituí-lo em nossa classe assim:

class User: 

    firstName = ''
    lastName = ''
    ...

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

e ao correr

print(user)

ele irá chamar a função __str__(self) e imprimir o firstName e o lastName

Amirouche Zeggagh
fonte
6

str() é o equivalente.

No entanto, você deve filtrar sua consulta. No momento, sua consulta é da all()Todo.

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

ou

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

dependendo de como você está definindo o autor no modelo Todo. A StringPropertyou UserProperty.

Nota nicknameé um método. Você está passando o método e não o resultado nos valores do modelo.

Tim Hoffman
fonte
Obrigado pela resposta! Vou tentar implementar o filtro agora. Estou um pouco confuso sobre o apelido. Eu já brinquei com isso antes e fui capaz de manipulá-lo como qualquer outra string e enviá-lo pelo valor do modelo muito bem. Estou esquecendo de algo? Ah, e o autor é um UserProperty. Vou adicionar isso à minha pergunta original.
Amru E.
Eu não uso modelos de django, então não sei o que eles farão. Alguns sistemas de modelos chamarão automaticamente os callables (apelido ())
Tim Hoffman
Você se importa em explicar brevemente o que o filtro faria? Não tenho certeza de qual é a função real do meu todos = Todo.all ().
Amru E.
Como você pode ver no código de exemplo, o filtro é um argumento de consulta, especificamente a propriedade do autor = algum valor. Você realmente deve gastar algum tempo lendo os documentos, isso vai economizar muito tempo. developers.google.com/appengine/docs/python/datastore fala sobre o armazenamento de dados e como obter / colocar e consultar dados.
Tim Hoffman
2

Você deve definir o __unicode__método em seu modelo, e o modelo o chamará automaticamente quando você fizer referência à instância.

Daniel Roseman
fonte
2

Na função post ():

todo.author = users.get_current_user()

Portanto, para obter str (todo.author), você precisa de str (users.get_current_user ()). O que é retornado pela função get_current_user ()?

Se for um objeto, verifique se ele contém uma função str () "?

Acho que o erro está aí.

sinhayash
fonte
users.get_current_user () retorna um objeto Usuário que tem um apelido () para fornecer um nome legível para o usuário. Eu estava tendo problemas para entender o apelido corretamente, mas descobri. Obrigado!
Amru E.