模型管理器和获取查询的模型方法

1 投票
1 回答
1507 浏览
提问于 2025-04-18 01:07

我有一个模型叫做 customer。我还为这个模型创建了一个管理器,并添加了一个叫 QuerySet 的类,这个类里面有一些特定的方法,比如 add_meta()

当我使用 Customers.objects.filter().add_meta() 时,我可以获取每个实例的所有元信息。但当我使用 Customer.objects.get(pk=1) 时,就不能用 meta_data() 这个方法了。

这是我的代码。

可重用的管理器

class CustomerManager(models.Manager):
    """A re-usable Manager to access a custom QuerySet"""

    def __getattr__(self, attr, *args):
        try:
            return getattr(self.__class__, attr, *args)
        except AttributeError:
            return getattr(self.get_query_set(), attr, *args)

    def get_query_set(self):
        return self.model.QuerySet(self.model)

模型

class Project(models.Model):
    objects = ProjectManager()

    class QuerySet(QuerySet):

        def add_meta(self):
            return self.extra(
                select={"priority": "COALESCE(bm_rank, sales_rank, created_at)",
                        "size": "order_size_price*order_size_weight",
                        "revenue": "current_selling_price*order_size_weight"
                },
                order_by=["priority"])

尝试过以下方法

Project.objects.filter(pk=5).add_meta().get().size

这个方法没成功

Project.objects.get(pk=5).add_meta()

有没有人知道我怎么才能在使用 get 的时候,依然能用 add_meta,并且和现有的代码一起使用。

1 个回答

1

你可以直接在你的模型类里添加一些属性,因为你的元信息只涉及一些简单的计算:

class Project(models.Model):
    # your fields....


    @property
    def size(self):
        return self.order_size_price * self.order_size_weight


# now this should work for every Project instance:
project = Project.objects.get(pk=1)
print project.size

如果你需要对这些“计算出来的”属性进行一些筛选,你仍然可以使用额外的选择...

撰写回答