Skip to main content
 首页 » 编程设计

python之如何枚举实体的反向引用

2025年05月04日12mfryf

在这种情况下,company.py 包含:

from django.utils import simplejson 
 
class Company(db.Model): 
    name=db.StringProperty() 
    address=db.StringProperty() 
 
    def to_JSON(): 
        d = dict([(p, unicode(getattr(self, p))) for p in self.properties()]) 
        return simplejson.dumps(d) 

office.py 包含:

from company import Company 
 
class Office(db.Model): 
    name = db.StringProperty() 
    company = db.ReferenceProperty(Company, collection_name='offices') 

模块 3 包含:

from company import Company 
 
class Region(db.Model): 
    name = db.StringProperty() 
    company = db.ReferenceProperty(Company, collection_name='regions') 

这是我需要做的事情的一个简化示例,但应该很好地捕捉它......我需要 Company 能够将自己表达为 JSON 字符串,并且它不知道其他类(Office 和区域)引用它。这适用于普通属性:

c = Company(name='A Company',address='123 Main St, New York, NY 12345') 
c.put() 
 
dallas = Office(name='Dallas',company=c) 
dallas.put() 
 
ny = Office(name='New York',company=c) 
ny.put() 
 
northeast = Region(name='NorthEast',company=c) 
northeast.put() 
 
southwest = Region(name='SouthWest',company=c) 
southwest.put() 
 
logging.info('Company as JSON: %s' % c.to_JSON()) 

我得到的输出是:

{"name": "A Company", "address": "123 Main St, New York, NY 12345"} 

所以 properties() 包含预期的实体属性,但我还想包含关联对象的 ReferenceProperty 属性的反向引用。本质上,我正在寻找的只是反向引用 (collection_name) 名称的列表,因为我知道它们代表查询,但我找不到任何方法来枚举反向引用名称本身。

请记住,这段代码实际上并不代表真正的代码,它已经大大简化了。现在这个工作:

offices = getattr(company, 'offices') 

所以我期待看到的是:

{"name": "A Company", "address": "123 Main St, New York, NY 12345",  
 "offices": "<db.Query object at 0x110e992d0>",  
 "regions": "<db.Query object at 0x110e99300>" 
} 

我实际上并不需要将反向引用“offices”和“regions”包含在 properties() 枚举中,但它们以某种方式检查了唯一性(我不能,例如,在 Company 中也有一个名为“offices”的 StringProperty),因此必须有一种方法来枚举它们。有人知道方法吗?

请您参考如下方法:

唯一性检查只是针对类字典(即为类对象提供名称和值之间映射的内部对象)。您可以通过检查 Company.__dict__ 来迭代这些。不过,这包括一切 - 内置 Python object 的所有属性、特性和方法,同样适用于 db.Model 和任何其他父类。

您最好的选择是遍历类字典,检查每个项目以查看它是否是 _ReverseReferenceProperty 的实例:

for propname, prop in Company.__dict__.iteritems(): 
  if isinstance(prop, db._ReverseReferenceProperty): 
    # Do something with prop, such as getting a query with getattr(a_company, propname).