Czy Python ma odpowiednik toString () i czy mogę przekonwertować element db.Model na String?

87

Piszę aplikację z listą zadań do zrobienia, aby pomóc sobie w rozpoczęciu pracy z Pythonem. Aplikacja działa w GAE i przechowuję elementy do wykonania w magazynie danych. Chcę pokazać im wszystkie przedmioty i tylko jemu. Problem w tym, że aplikacja wyświetla obecnie wszystkie pozycje wszystkim użytkownikom, więc ja widzę, co piszesz, a ty widzisz, co piszę. Pomyślałem, że rzutowanie obiektu todo.author na łańcuch i sprawdzenie, czy pasuje do nazwy użytkownika, byłoby dobrym początkiem, ale nie wiem, jak to zrobić.

To jest to, co mam w moim 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('/')

W moim index.html miałem to pierwotnie:

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

ale chciałbym wyświetlać elementy tylko użytkownikowi, który je utworzył. Myślałem, żeby spróbować

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

bezskutecznie. Lista jest pusta. Założyłem, że dzieje się tak, ponieważ autor todo.autor nie jest ciągiem znaków. Czy mogę odczytać wartość jako ciąg, czy mogę rzutować obiekt na String?

Dzięki!

Edycja: Oto moja klasa Todo

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

Czy zmiana autora na StringProperty wpłynie na coś negatywnego? Może mogę całkowicie zrezygnować z castingu.

Amru E.
źródło

Odpowiedzi:

92

W Pythonie str()metoda jest podobna do toString()metody w innych językach. Nazywa się to przekazaniem obiektu do konwersji na łańcuch jako parametr. Wewnętrznie wywołuje __str__()metodę obiektu parametru, aby uzyskać jego reprezentację w postaci ciągu.

W tym przypadku jednak porównujesz UserPropertyautora z bazy danych, która jest typu users.Userz ciągiem pseudonimu. Zamiast tego będziesz chciał porównać nicknamewłaściwość autora z todo.author.nicknamew szablonie.

Jeff Lockhart
źródło
Dziękuję za odpowiedź. Podczas próby str (todo.author) w szablonie pojawia się następujący błąd: TemplateSyntaxError: Could not parse the remainder: '(todo.author)' from 'str(todo.author)'jakieś pomysły?
Amru E.
1
Spróbuj umieścić cytaty w ten 'str(todo.author)'sposób. Nie mam doświadczenia z szablonami Django, ale wygląda na to, że jego mechanizm parsowania jest zawieszany w nawiasach po strnazwie funkcji. Lub możesz raczej otrzymać właściwość string autora, prawdopodobnie coś podobnego todo.author.nickname, bez potrzeby str()wywołania.
Jeff Lockhart
W końcu udało mi się to! Użyłem todo.author.nickname w mojej instrukcji if i sprawdziłem, czy ta wartość jest zgodna z pseudonimem bieżącego użytkownika. Przeredaguj swoją odpowiedź i dołącz ją, abym mógł ją zaakceptować.
Amru E.
35

W Pythonie możemy skorzystać z __str__()metody.

Możemy to zmienić w naszej klasie w następujący sposób:

class User: 

    firstName = ''
    lastName = ''
    ...

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

i podczas biegania

print(user)

wywoła funkcję __str__(self) i wydrukuje firstName i lastName

Amirouche Zeggagh
źródło
6

str() jest odpowiednikiem.

Jednak powinieneś filtrować swoje zapytanie. W tej chwili Twoje zapytanie to all()Todo's.

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

lub

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

w zależności od tego, co definiujesz autora, jak w modelu Todo. A StringPropertylub UserProperty.

Uwaga nicknameto metoda. Przekazujesz metodę, a nie wynik w wartościach szablonu.

Tim Hoffman
źródło
Dzięki za odpowiedź! Pójdę dalej i spróbuję teraz zaimplementować filtr. Jestem trochę zdezorientowany co do pseudonimu. Bawiłem się nim wcześniej i byłem w stanie manipulować nim jak każdym innym ciągiem i wysłać go przez wartość szablonu po prostu dobrze. Czy coś mi brakuje? Aha, a autor jest własnością użytkownika. Dodam to do mojego pierwotnego pytania.
Amru E.
Nie używam szablonów django, więc nie wiem, co zrobią. Niektóre systemy szablonów automatycznie wywołują wywołania (nick ())
Tim Hoffman,
Czy możesz krótko wyjaśnić, co zrobiłby filtr? Nie jestem pewien, jaka jest rzeczywista funkcja mojej funkcji todos = Todo.all ().
Amru E.
Jak widać z przykładowego kodu, filtr jest argumentem zapytania, a konkretnie właściwością autora = pewną wartością. Naprawdę powinieneś spędzić trochę czasu na czytaniu dokumentów, zaoszczędzi ci to dużo czasu. developers.google.com/appengine/docs/python/datastore mówi o magazynie danych oraz o tym, jak pobierać / umieszczać i wyszukiwać dane.
Tim Hoffman
2

Powinieneś zdefiniować __unicode__metodę w swoim modelu, a szablon wywoła ją automatycznie, gdy odwołasz się do instancji.

Daniel Roseman
źródło
2

W funkcji post ():

todo.author = users.get_current_user()

Tak więc, aby uzyskać str (todo.author), potrzebujesz str (users.get_current_user ()). Co jest zwracane przez funkcję get_current_user ()?

Jeśli jest to obiekt, sprawdź, czy zawiera funkcję str () "?

Myślę, że to błąd.

sinhayash
źródło
users.get_current_user () zwraca obiekt użytkownika, który ma nick (), aby zapewnić czytelną nazwę dla użytkownika. Miałem problem z poprawnym uzyskaniem pseudonimu, ale rozgryzłem to. Dzięki!
Amru E.