'模型不是不可变的'TypeError

时间:2013-09-13 19:37:47

标签: google-app-engine python-2.7 app-engine-ndb

我得到了这个追溯;

--- Trimmed parts ---
File "C:\Users\muhammed\Desktop\gifdatabase\gifdatabase.py", line 76, in maketransaction
    gif.tags = list(set(gif.tags + tags))
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\ext\ndb\model.py", line 2893, in __hash__
    raise TypeError('Model is not immutable')
TypeError: Model is not immutable

以下是我的代码的相关部分;

class Gif(ndb.Model):
    author = ndb.UserProperty()
    #tags = ndb.StringProperty(repeated=True)
    tags = ndb.KeyProperty(repeated=True)

    @classmethod
    def get_by_tag(cls,tag_name):
        return cls.query(cls.tags == ndb.Key(Tag, tag_name)).fetch()

class Tag(ndb.Model):
    gif_count = ndb.IntegerProperty()

class PostGif(webapp2.RequestHandler):

    def post(self):

        user = users.get_current_user()
        if user is None:
            self.redirect(users.create_login_url("/static/submit.html"))
            return

        link = self.request.get('gif_link')
        tag_names = shlex.split(self.request.get('tags').lower())


        @ndb.transactional(xg=True)
        def maketransaction():
            tags = [Tag.get_or_insert(tag_name) for tag_name in tag_names]
            gif = Gif.get_or_insert(link)

            if not gif.author: # first time submission
                gif.author = user

            gif.tags = list(set(gif.tags + tags))
            gif.put()
            for tag in tags:
                tag.gif_count += 1
                tag.put()

        if validate_link(link) and tag_names:
            maketransaction()
            self.redirect('/static/submit_successful.html')
        else:
            self.redirect('/static/submit_fail.html')

gif.tags = list(set(gif.tags + tags))行有什么问题?

1 个答案:

答案 0 :(得分:2)

您正在插入标签而非钥匙,您需要访问

tags = [Tag.get_or_insert(tag_name).key .....]

但你也可以像这样把它作为一个网络跳

futures = [Tag.get_or_insert_async(tag_name) for tag_name in tag_names]
futures.append(Gif.get_or_insert_async(link))
ndb.Future.wait_all(futures)
gif = futures.pop().get_result()
tags = [future.get_result() for future in futures]

但这不是一个问题,只是一个建议^,对于.key更清楚的回答

gif.tags = gif.tags + [tag.key for tag in tags]
# or 
gif.tags.extend([tag.key for tag in tags])
相关问题