2010-10-20 88 views
2

在我的一个Django模型中,我必须为每个模型实例添加特定的代码。现在,我想知道实施这个的好方法是什么。我目前的尝试会导致一个很大的,难以理解的陈述。Django模型实例特定代码

考虑以下模型:

class Foo(models.Model): 
    name = models.CharField(max_length=255) 

    def do_instance_specific_stuff(self, arg): 
     if self.id == 1: 
      do_X(arg) 
     elif self.id == 2: 
      do_Y(arg) 
     else: 
      do_Z() 

眼下,有自定义代码大约20模型实例,它会留在这个幅度。任何想法或模式如何以清晰可读的方式实现?

感谢您的任何帮助。

+3

这是一个*糟糕的*想法。你为什么认为你需要它? – 2010-10-20 08:21:00

+0

@Ignacio Vazquez-Abrams:有问题的模型存储供应商实例,每个供应商都有关于如何联系他们某些服务的具体规则。这是我可以存储在模型字段中的任何东西,我必须为每个模型实例执行不同的代码。我很高兴看到有什么提示可以或应该如何实施。 – Haes 2010-10-20 08:45:28

+0

您确实有多个子类(每个供应商一个)。你从来没有“特定于实例”的功能。你所拥有的是“特定模型”特征以及非常少数的模型实例。通常只有一个。我们也是这样做的。 – 2010-10-20 11:01:14

回答

3

我将另一个字段添加到模型,vendor。然后,每个厂商的方法添加到您的模型,并与GETATTR调用它们:

class Foo(models.Model): 
    name = models.CharField(max_length=255) 
    vendor = models.CharField(max_length=50) 

    def vendor_fedex(self, arg): 
     blah blah 

    def vendor_ups(self, arg): 
     blah blah 

    def vendor_usps(self, arg): 
     blah blah 

    def do_instance_specific_stuff(self, arg): 
     fn = getattr(self, "vendor_"+self.vendor, None) 
     if not fn: 
      raise Exception("Uh-oh, bad vendor") 
     fn(arg) 

取决于id特定值显得脆弱。在您的数据模型中,每个供应商字符串只会出现一次,但它会是可读性和可塑性的。如果getattr找不到供应商代码,您可以决定要执行的操作。

1

的常见模式是使用dict

stuff_per_id = {1 : do_X, 2 : do_Y, ...} 
def do_instance_specific_stuff(arg): 
    try: 
     stuff_per_id[self.id](arg) 
    except KeyError: 
     do_Z() 

虽然你真的不应该这样做。在您的模型中添加额外的字段会更好,这表示应在arg上为此实例运行哪些代码。 dict模式可能仍然有用。

编辑:如果您的实例特定功能中的任何一个可能引起KeyError,则上述执行do_Z。如果你不希望出现这种情况,加上未使用的参数do_Z和使用下列内容:

def do_instance_specific_stuff(arg): 
    try: 
     f = stuff_per_id[self.id] 
    except KeyError: 
     f = do_Z 
    f(arg) 
相关问题