2009-08-21 7 views
5

Chciałbym zapytać, co to znaczy "AttributeError:" Unicode "obiekt nie ma atrybutu" has_key "" Tutaj jest pełna ślad stosu:Python co to znaczy "AttributeError:" Unicode "obiekt nie ma atrybutu" has_key ""

Traceback (most recent call last): 
    File  "D:\Projects\GoogleAppEngine\google_appengine\google\appengine\ext\webapp\__init__.py", line 509, in __call__ 
    handler.post(*groups) 
    File "D:\Projects\workspace\foo\src\homepage.py", line 71, in post 
    country=postedcountry 
    File "D:\Projects\GoogleAppEngine\google_appengine\google\appengine\ext\db\__init__.py", line 656, in __init__ 
    prop.__set__(self, value) 
    File "D:\Projects\GoogleAppEngine\google_appengine\google\appengine\ext\db\__init__.py", line 2712, in __set__ 
    value = self.validate(value) 
    File "D:\Projects\GoogleAppEngine\google_appengine\google\appengine\ext\db\__init__.py", line 2742, in validate 
    if value is not None and not value.has_key(): 
AttributeError: 'unicode' object has no attribute 'has_key' 

opiszę trochę więcej o sytuacji:

  • Najpierw stworzył models.py który ma db.Model dla CMSRequest kraj, który ma atrybut odniesienia do klasy CMSCountry

    class CMSRequest(db.Model): 
        country = db.ReferenceProperty(CMSCountry, required=True) 
    
    class CMSCountry(db.Model): 
        name = db.StringProperty(required=True) 
    
  • Potem stworzyliśmy klasę bulkloader importowania danych do CMSCountry

  • W postaci, użytkownik może wybrać kraj z rozwijanej listy w dół, wyniki są wysłane z powrotem i zapisz przedmiotem CMSRequest

    def post(self): 
        postedcountry = self.request.get('country') 
        cmsRequest = models.CMSRequest(postedcountry) 
    

Może znalazłem rozwiązanie na moje pytanie, to dlatego, że nie zostały przekształcone oddelegowanego klucz CMSCountry Wróć, aby zapisać się do CMSRequest.

Dziękuję wszystkim!

Odpowiedz

6

W tej linii:

if value is not None and not value.has_key(): 

value jest ciągiem znaków Unicode. To wygląda kodu spodziewa się, że jest to db.Model,

(Z tego co widzę, has_key to metoda db.Model, jak również metoda słowników Python, ale musi to być jeden db.Model bo to jest wywoływana bez argumentów.)

Czy przekazujesz ciąg znaków do interfejsu API GAE, który oczekuje wartości db.Model?

+0

Witam, edytowałem pytanie z jeszcze jednym kodem –

+0

@Hoang: Wygląda na to, że potrzebujesz czegoś podobnego do 'cmsRequest = models.CMSRequest (country = models.CMSCountry (postedcountry))' (ja nie wiedzieć, czy to jest właściwy sposób, aby uzyskać 'CMSCountry' z ciągu, ale widzisz, co mówię). – RichieHindle

+1

Dziękuję Richie, na podstawie Twojej sugestii, mam zmodyfikowany kod w następujący sposób: def post (self): postedcountry = self.request.get ('państwo') kraj = models.CMSCountry.get (postedcountry) cmsRequest = models.CMSRequest (kraj) Klucz kraju powinien zostać wypełniony w html dla opcji, a funkcja sendcountry będzie miała klucz CMSCountry. –

1

Jeśli czytasz traceback, to będzie powiedzieć dokładnie, co się dzieje:

if value is not None and not value.has_key(): 
AttributeError: 'unicode' object has no attribute 'has_key' 

Co mówi ta jest zmienna value którego używasz nie posiada atrybut has_key. I, co ci mówisz, to, że twoja zmienna value nie jest słownikiem, ponieważ wygląda na to, że oczekujesz ... zamiast tego, jest to obiekt unicode, który jest w zasadzie ciągiem.

2

Uwaga: normalnie „mapowania” typy w Pythonie (słowniki i słownika ... jak klas, takich jak różnego rodzaju dBm (indeksowanego pliku) i niektóre DBMS/interfejsy ORM ... będzie wdrażać metodę has_key()

.

Jakoś Otrzymałam Unicode (string) obiekt do tego stwierdzenia, gdy spodziewali się mieć jakiś słownika lub innego odniesienia do obiektu mapowania.

W ogólnym AttributeError oznacza, że ​​poplątane Państwa obiekt wiązania (zmienna przypisania). Podałeś nazwę obiektowi, który nie był zamierzony (lub czasami oznacza to y) masz literówkę typu ".haskey()" zamiast has_key() ... itd.).

Przy okazji: użycie has_key() jest nieco przestarzałe. Zwykle lepiej jest przetestować swoje pojemniki za pomocą operatora Python in (który niejawnie wywołuje __contains__() --- i który działa na listach, ciągach i innych sekwencjach, a także typach mapowania).

także value.has_key() podniesie błąd, nawet jeśli value były słownikiem ponieważ metoda .has_key() wymaga argumentu.

W twoim kodzie albo jawnie przetestuję dla if postedcountry is not None: ... albo podam twoje .get() z (opcjonalnie) domyślnym dla "wysłanego kraju".

Jak chcesz obsłużyć sytuację, w której request nie ma wysłanych? Czy chcesz założyć, że został wysłany z jakiegoś konkretnego ustawienia domyślnego? Wymuś przekierowanie do strony, która wymaga podania przez użytkownika wartości dla tego elementu formularza? Powiadomić hiszpańską inkwizycję?

1

Próbujesz ustawić ciąg do ReferenceProperty. Pole "kraju" CMSCountry to db.ReferenceProperty, które pobiera obiekt db.Key lub CMSCountry, ale próbujesz ustawić go na ciąg.

Należy robić coś takiego:

def post(self): 
    postedcountry = self.request.get('country') 
    country = models.CMSCountry.all().filter('name =', postedcountry) 
    if not country: 
    # Couldn't find the country 
    else: 
    cmsRequest = models.CMSRequest(country=country) 

Proszę file a bug o niezbyt pomocny komunikat o błędzie, choć.

3

Twój problem polega na tym, że funkcja sendcountry jest ciągiem znaków, a nie obiektem kraju. Wartości pobierane z self.request.get są ciągami wartości zmiennych przekazywanych przez przeglądarkę.

Musisz wyszukać obiekt country za pomocą GQL. Dokładnie w jaki sposób to zrobisz, zależy od tego, co dokładnie zwraca pole kraju formularza HTML, Klawisz obiektu ?, nazwa kraju?

def post(self): 
    postedcountry = self.request.get('country') 

    # <-------- Need to look up a country here !!!!! 

    cmsRequest = models.CMSRequest(country=postedcountry) 
0

Metoda has_key() obiektu słownika jest nieaktualna w wersji 3.0 - zamiast tego użyj wyrażenia "in". Jeśli używasz starej biblioteki w wersji 3.x, musisz wprowadzić zmiany kodu, aby ją dostosować.

Powiązane problemy