4

我有几个模型通过 ForeignKeys 关系相互连接。
这种层次结构中的主要部分包含一个所有者字段。

我想为所有这些模型创建一个自定义管理器,根据调用它的模型更改返回的查询集。

我知道经理可以访问self.model以获取它所附加的模型。

Class Main(models.Model)
  owner=models.ForeignKey (User)
  owned = OwnedManager()

Class Second(models.Model)
  main=models.ForeignKey('Main')
  owned = OwnedManager()

Class Third(models.Model)
  second=models.ForeignKey('Second')
  owned = OwnedManager()

我希望我的客户经理有这种行为:

class OwnedManager(models.Manager): 
    def get_owned_objs(self, owner):
        if self.model == 'Main': # WRONG: How do I get the model name?
            owned_main = self.filter(owner=owner)
            return owned_main
        elif self.model == 'Second':
            owned_second = self.filter(main__owner=owner)
            return owned_second
        else:
            owned_third = self.filter(second__main__owner=owner)
            return owned_third

为了在不同的模型中以一致的方式调用它,如下所示:

main_object.owned.get_owned_objs(owner=user1) # of the Model Main
second_object.owned.get_owned_objs(owner=user1) # of the Model Second
third_object.owned.get_owned_objs(owner=user1) # of the Model Third

问题:

  • self.model == 'Main'是错的。我没有这样的型号名称。有没有办法得到它?
  • 这有效率吗?你知道一个更好的方法来实现这个吗?也许自定义经理继承?

编辑-我的解决方案: 下面接受的答案是一个很好的解决方案,但我还找到了一种方法来获取调用自定义管理器的特定模型的模型名称,即:

if self.model.__name__ == 'Main':

这里的关键是属性__name__

4

1 回答 1

5

1)制作抽象模型

class AbstractModel(models.Model):
    class Meta(models.Meta):
        abstract = True

    objects = OwnedManager()

2) 从 AbstractModel 继承你的模型,在 meta 中放一些键

class Model(AbstractModel)
    class Meta(AbstractModel.Meta):
        filter_key = 'some_key'

3) 重新设计你的 OwnedManager

class OwnedManager(models.Manager): 
    def get_owned_objs(self, owner):
        if hasattr(self.model._meta, 'filter_key'):
            return self.filter(**{self.model._meta.filter_key: owner})

现在您可以SomeModel.objects.get_owned_objs(owner=user1)在任何继承的模型中 使用,filter_key无需获取模型名称即可设置。

于 2013-07-31T11:17:18.337 回答