I would like to ask what does it mean "AttributeError: 'unicode' object has no attribute 'has_key'" Here is the full stack trace:
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'
Let me describe a little bit more about the situation:
First I created the models.py that has the db.Model for CMSRequest which has an attribute country that reference to the CMSCountry class
class CMSRequest(db.Model):
country = db.ReferenceProperty(CMSCountry, required=True)
class CMSCountry(db.Model):
name = db.StringProperty(required=True)
Then, I created a bulkloader class to import the data into the CMSCountry
In the form, user can select the country from the drop down list box, the results are posted back and save to the CMSRequest object
def post(self):
postedcountry = self.request.get('country')
cmsRequest = models.CMSRequest(postedcountry)
Maybe I have found the solution to my question, it is because I have not converted the posted key of CMSCountry back to save to the CMSRequest.
Thank you everyone!
In this line:
if value is not None and not value.has_key():
value
is a unicode string. It looks like the code is expecting it to be a db.Model
,
(From what I can see, has_key
is a method of db.Model
, as well as a method of Python dictionaries, but this must be the db.Model
one because it's being called with no arguments.)
Are you passing a string to a GAE API that expects a db.Model
?
Your problem is that postedcountry is a string and not a country object. Values retrieved from self.request.get are the string values of variables passed by the browser.
You need to look up a country object using some GQL. Exactly how you do that will depend on what exactly the country field of your HTML form is returning , Object Key?, country name?
def post(self):
postedcountry = self.request.get('country')
# <-------- Need to look up a country here !!!!!
cmsRequest = models.CMSRequest(country=postedcountry)
Note: normally "mapping" types in Python (dictionaries and dictionary like classes ... such as various types of dbm (indexed file) and some DBMS/ORM interfaces ... will implement a has_key()
method.
Somehow you have gotten a Unicode (string) object into this statement when you were expecting to have some sort of dictionary or other mapping object reference.
In general AttributeError means that you have tangled up your object bindings (variable assignments). You've given a name to some object other than the type that you intended. (Or sometimes it means you have a typo like ".haskey()" instead of has_key()
... etc).
BTW: the use of has_key()
is somewhat dated. Normally it's better to test your containers with the Python in
operator (which implicitly calls __contains__()
--- and which works on lists, strings, and other sequences as well as mapping types).
Also value.has_key()
would raise an error even if value
were a dictionary since the .has_key()
method requires an argument.
In your code I would either explicitly test for if postedcountry is not None:
... or I'd supply your .get()
with an (optional) default for "postedcountry."
How do you want to handle the situation where request
had no postedcountry? Do you want to assume it's being posted from some particular default? Force a redirection to some page that requires the user to supply a value for that form element? Alert the Spanish Inquisition?
If you read the traceback, it'll tell you exactly what is going on:
if value is not None and not value.has_key():
AttributeError: 'unicode' object has no attribute 'has_key'
What this says is the the value
variable which you're using doesn't have the has_key
attribute. And, what it's telling you is that your value
variable isn't a dictionary, as it looks like you're expecting...instead, it's a unicode object, which is basically a string.
You're attempting to set a string to a ReferenceProperty. The 'country' field of CMSCountry is a db.ReferenceProperty, which takes a db.Key or a CMSCountry object, but you're attempting to set it to a string.
You should be doing something like this:
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)
Please do file a bug about the rather unhelpful error message, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With