Есть ли у Python эквивалент toString (), и могу ли я преобразовать элемент db.Model в String?

87

Я пишу приложение со списком ToDo, чтобы помочь себе начать работу с Python. Приложение работает в GAE, и я храню задачи в хранилище данных. Я хочу показать им все, и только им. Проблема в том, что приложение в настоящее время отображает все элементы для всех пользователей, поэтому я могу видеть, что вы пишете, и вы видите, что пишу я. Я думал, что приведение моего объекта todo.author к строке и проверка, соответствует ли он имени пользователя, было бы хорошим началом, но я не могу понять, как это сделать.

Это то, что у меня есть в моем 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('/')

В моем index.html изначально у меня было это:

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

но я хотел бы отображать элементы только для пользователя, который их создал. Я думал попробовать

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

но безрезультатно. Список оказывается пустым. Я предположил, что это потому, что todo.author не является строкой. Могу ли я прочитать значение как строку или преобразовать объект в String?

Благодарность!

Изменить: вот мой класс Todo

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

Повлияет ли на что-нибудь негативное изменение моего автора на StringProperty? Может, вообще откажусь от кастинга.

Амру Э.
источник

Ответы:

92

В Python str()метод аналогичен toString()методу в других языках. Это называется передачей объекта для преобразования в строку в качестве параметра. Внутри он вызывает __str__()метод объекта параметра, чтобы получить его строковое представление.

В этом случае, однако, вы сравниваете UserPropertyавтора из базы данных, тип которого users.Userсоответствует строке псевдонима. nicknameВместо этого вы захотите сравнить свойство автора со свойством todo.author.nicknameв вашем шаблоне.

Джефф Локхарт
источник
Спасибо за ответ. При попытке использовать str (todo.author) в шаблоне появляется следующая ошибка: TemplateSyntaxError: Could not parse the remainder: '(todo.author)' from 'str(todo.author)'какие-нибудь идеи?
Амру Э.
1
Попробуйте поместить такие кавычки 'str(todo.author)'. У меня нет опыта работы с шаблонами Django, но похоже, что его механизм синтаксического анализа зависает от скобок после имени strфункции. Или вы можете получить строковое свойство автора, возможно, что-то вроде этого todo.author.nickname, без необходимости str()вызова.
Джефф Локхарт
Наконец-то я заработал! Я использовал todo.author.nickname в своем операторе if и проверил, совпадает ли это значение с ником текущего пользователя. Измените свой ответ, включив его, чтобы я мог принять его.
Амру Э.
35

В Python мы можем использовать __str__()метод.

Мы можем переопределить это в нашем классе следующим образом:

class User: 

    firstName = ''
    lastName = ''
    ...

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

и при беге

print(user)

он вызовет функцию __str__(self) и напечатает firstName и lastName

Амируш Зегга
источник
6

str() эквивалент.

Однако вы должны фильтровать свой запрос. На данный момент ваш запрос принадлежит all()Todo.

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

или

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

в зависимости от того, что вы определяете как автора, как в модели Todo. A StringPropertyили UserProperty.

Примечание nickname- это метод. Вы передаете метод, а не результат в значениях шаблона.

Тим Хоффман
источник
Спасибо за ответ! Я продолжу и попробую реализовать фильтр сейчас. Хотя меня немного смущает ник. Я играл с ним раньше, и я мог манипулировать им, как любой другой строкой, и просто отправлять ее через значение шаблона. Я что-то упускаю? Да, и автор - это UserProperty. Я добавлю это к своему первоначальному вопросу.
Амру Э.
Я не использую шаблоны django, поэтому не знаю, что они будут делать. Некоторые системы шаблонов автоматически вызывают вызываемые объекты (ник ())
Тим Хоффман
Не могли бы вы вкратце объяснить, что будет делать фильтр? Я не уверен, какова фактическая функция моего todos = Todo.all ().
Амру Э.
Как видно из кода примера, фильтр - это аргумент запроса, а именно свойство автора = некоторое значение. Вы действительно должны потратить некоторое время на чтение документации, это сэкономит вам много времени. developers.google.com/appengine/docs/python/datastore рассказывает о хранилище данных и о том, как получать / размещать и запрашивать данные.
Тим Хоффман
2

Вы должны определить __unicode__метод в своей модели, и шаблон будет вызывать его автоматически, когда вы ссылаетесь на экземпляр.

Дэниел Розман
источник
2

В функции post ():

todo.author = users.get_current_user()

Итак, чтобы получить str (todo.author), вам понадобится str (users.get_current_user ()). Что возвращает функция get_current_user ()?

Если это объект, проверьте, содержит ли он функцию str () "?

Я думаю, что ошибка в этом.

Sinhayash
источник
users.get_current_user () возвращает объект User, у которого есть nickname (), чтобы предоставить читаемое имя пользователю. У меня были проблемы с получением псевдонима, но я разобрался. Благодарность!
Амру Э.