抽象Django模型管理

2024-10-03 11:12:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我在这里缺乏Python元编程知识。假设我有以下内容:

class OwnCompanyManager(models.Manager):
    """Only companies of this user"""
    def get_queryset(self, user):
        if user.is_superuser:
            return super(OwnCompanyManager, self).get_queryset()
        return super(OwnCompanyManager, self).get_queryset().filter(
            companyuser__user=user)


class OwnPublisherManager(models.Manager):
    """Only publishers of this user's company"""
    def get_queryset(self, user):
        if user.is_superuser:
            return super(OwnPublisherManager, self).get_queryset()
        return super(OwnPublisherManager, self).get_queryset().filter(
            company__companyuser__user=user)

class Company(models.Model):
    name = models.CharField(max_length=45)

    objects = models.Manager()
    own = OwnCompanyManager()


class Publisher(models.Model):
    company = models.ForeignKey(Company)
    allow_latest_dev = models.BooleanField(default=False)
    domains_blocked = models.BooleanField(default=False)

    objects = models.Manager()
    own = OwnPublisherManager()

我还有很多。我不喜欢复制粘贴模板Own(Publisher|Company|Etcetra)Manager)。唯一的变化是,正如你所看到的,过滤器。在

我如何抽象Own(InsertModelNameHere)Manager并从CompanyPublisher和其他模型中使用它?我想在管理器定义中指定筛选器kwargs。在


Tags: selfonlygetreturnmodelsmanagercompanypublisher
2条回答

受丹尼尔回答的启发:

class OwnManager(models.Manager):
    def __init__(self, key):
        super(OwnManager, self).__init__()
        self.k = key

    def get_queryset(self, user):
        if user.is_superuser:
            return super(OwnManager, self).get_queryset()
        return super(OwnManager, self).get_queryset().filter(**{self.k: user})


class Company(models.Model):
    name = models.CharField(max_length=45)

    objects = models.Manager()
    own = OwnManager("companyuser__user")


class Publisher(models.Model):
    company = models.ForeignKey(Company)
    allow_latest_dev = models.BooleanField(default=False)
    domains_blocked = models.BooleanField(default=False)

    objects = models.Manager()
    own = OwnManager("company__companyuser__user")

这样我就不想为每个模型创建一个愚蠢的类。在

谢谢丹尼尔。在

这里不需要元编程或任何特别聪明的东西。你只需要提取变化的部分。在本例中,它只是filter的参数:可以使用字典形式的参数传递,并将过滤器作为字符串存储在类属性中。在

class AbstractManager(models.Manager):
    def get_queryset(self, user):
        if user.is_superuser:
            return super(AbstractManager, self).get_queryset()
        return super(AbstractManager, self).get_queryset().filter(**{self.filter: user})

class OwnCompanyManager(AbstractManager):
    filter = "companyuser__user"

class OwnPublisherManager(AbstractManager):
    filter = "company__companyuser__user"

相关问题 更多 >