这是一个创建于 5531 天前的主题,其中的信息可能已经有所发展或是发生改变。
    
    
    
        
        我的需求大概是这样,
发现某个用户有滥用行为,管理员将该用户挂起,再不删除实际数据的情况下,在前台显示中过滤掉被挂起用户所产生的内容。
1、通常情况下“用户”,与用户产生的“内容”的关系为:
(注意这里所说的“用户”不是Google Account或者其他GAE内置支持的用户类型。)
class User(db.Model):
    name = db.StringProperty()
class Story(db.Model):
    title = db.StringProperty()
    content = db.StringProperty()
    author = db.ReferenceProperty(User)
查询一个Story列表:
stories = Story.all().fetch(10)
2、加入封杀功能,自然的想到大概应该是这样做:
class User(db.Model):
    name = db.StringProperty()
    suspended = db.BooleanProperty(default=False)
class Story(db.Model):
    title = db.StringProperty()
    content = db.StringProperty()
    author = db.ReferenceProperty(User)
查询一个Story列表:
stories = Story.all().filter("author.suspended =", False).fetch(10)
但是这个办法是错误的。什么都查不到。
Datastore是没有join操作的,所以不能在一个model的filter里限制另一个model的值。
3、目前我的比较笨的解决办法是这样:
我把Story也加一个suspended属性,挂起一个用户的同时将所所有该用户产生的内容一同挂起。
也就是:
def suspend_user(user):
   user.suspended=True
   user.put()
   stories=user.story_set.all().fetch(100)
   for story in stories:
      story.suspended=True
   db.put(stories)
这样做是考虑到挂起一个用户并不是非常频繁的操作,而查询用户产生的内容的操作经常会被用到。
但是这样一用才发现索引数量增加了差不多一倍啊。
4、有人说用IN来查询,但是文档中说这个最多不过30个,要是有人故意捣乱30个就太少了。并且带有IN的查询好像不能太频繁的用吧?
----------------
这个问题我在别的地方问过,总感觉一些解决办法不太好用。不知道有什么其他简洁高效办法么?
----------------
        
     
    
    
    
    
 
    4 条回复  •  1970-01-01 08:00:00 +08:00
     
    
    
        
        
        
        
            
                |  |  |      1summic      2010-09-09 19:45:50 +08:00 那么在story里面加一个字段标记一下呢?挂起的时候,更新他所有的story的这个字段 | 
        
         
    
    
    
        
        
    
    
    
        
        
        
        
            
                |  |  |      3Livid      2010-09-09 21:07:53 +08:00 via iPhone 可以在浏览器端用 JS 把内容藏起来,V2EX 的 block 就是这样实现的。 | 
        
         
    
    
    
        
        
        
        
            
                |  |  |      4darasion      2010-09-09 21:25:35 +08:00 @Livid  内容虽然用 js 隐藏了,但是一旦页面代码一旦出现敏感词还是会被重置的。 |