1

我正在做一个关于客户、产品和草稿的简单程序。

由于它们以某种方式相互引用,因此当我删除一种实体时,另一种实体可能会出错。

这是我所拥有的:

-客户.py

class Customer(db.Model):
    """Defines the Customer entity or model."""
    c_name      = db.StringProperty(required=True)
    c_address   = db.StringProperty()
    c_email     = db.StringProperty() ...

-draft.py

class Draft(db.Model):
    """Defines the draft entity or model."""
    d_customer      = db.ReferenceProperty( customer.Customer,
                                        collection_name='draft_set')
    d_address       = db.StringProperty()
    d_country       = db.StringProperty() ...

好的,现在我要做的是在删除客户之前检查客户是否有任何引用他的草稿。这是我正在使用的代码:

def deleteCustomer(self, customer_key):
    '''Deletes an existing Customer'''

    # Get the customer by its key
    customer = Customer.get(customer_key)

    if customer.draft_set: # (or customer.draft_set.count > 0...)
        customer.delete()

    else:
        do_something_else()

而现在,问题来了。如果我之前创建了一个包含选定客户的草稿,则完全没有问题,它会做必须做的事情。但是,如果我没有创建任何引用该客户的草稿,则在尝试删除他时,它将显示此错误:

AttributeError: 'Customer' object has no attribute 'draft_set'

我究竟做错了什么?是否需要始终创建包含客户的草稿以使 collection_name 属性“可用”?

编辑:我发现了错误是什么。由于我在不同的 .py 文件中都有这两个类,因此 GAE 似乎在“通过”包含该模型的文件的同时将实体加载到数据存储中。因此,如果我正在执行该程序,并且从不使用或导入该文件,则数据存储在此之前不会更新。现在我正在做的是:

from draft.py import Draft

在de“deleteCustomer()”函数内部,它终于可以正常工作了,但是因此我得到了一个可怕的“未使用警告”。

有没有其他方法可以解决这个问题?

4

2 回答 2

1

collection_name 属性是一个查询,因此它应该始终可用。

您可能缺少的是reference_class参数(查看ReferenceProperty 文档

class Draft(db.Model):
"""Defines the draft entity or model."""
    d_customer = db.ReferenceProperty(reference_class=customer.Customer, collection_name='draft_set')

以下应该有效:

if customer.draft_set.count():
    customer.delete()

请注意,customer.draft_set它将始终返回 true,因为它是生成的 Query 对象,因此您必须使用count()

于 2013-03-05T03:33:44.470 回答
0

有两种可能的解决方案:

  1. 丑陋的,坏的:如我编辑的问题中所述。

  2. 最佳实践:将所有模型放在一个文件(例如 models.py)中,如下所示:

    class Customer(db.Model):
    
        """Defines the Customer entity or model."""
    
        c_name      = db.StringProperty(required=True)
        c_address   = db.StringProperty()
        c_email     = db.StringProperty() ...
    
    class Draft(db.Model):
    
        """Defines the draft entity or model."""
        d_customer      = db.ReferenceProperty( customer.Customer,
                                    collection_name='draft_set')
        d_address       = db.StringProperty()
        d_country       = db.StringProperty() ...
    

简单的!

于 2015-05-04T14:33:26.473 回答