python 用于预定义值的 Django 模型类方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2213309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-04 00:04:39  来源:igfitidea点击:

Django model class methods for predefined values

pythondjangodjango-models

提问by J?rgen Lundberg

I'm working on some Django-code that has a model like this:

我正在处理一些具有如下模型的 Django 代码:

class Status(models.Model):
    code = models.IntegerField()
    text = models.CharField(maxlength=255)

There are about 10 pre-defined code/text-pairs that are stored in the database. Scattered around the codebase I see code like this:

数据库中存储了大约 10 个预定义的代码/文本对。分散在代码库周围,我看到这样的代码:

status = Status.objects.get(code=0) # successful
status = Status.objects.get(code=1) # failed

I would rather have a method for each so that the code would look something like this instead:

我宁愿为每个方法都有一个方法,以便代码看起来像这样:

status = Status.successful()
status = Status.failed()
etc...

Is this possible? I have looked in to the Manager-stuff but I haven't really found a way. Is it time to really RTFM?

这可能吗?我已经查看了经理的东西,但我还没有真正找到办法。是时候真正进行 RTFM 了吗?

In Java it would be a static method and in Ruby you would just define a method on self, but it's not that easy in Python, is it?

在 Java 中,它是一个静态方法,而在 Ruby 中,您只需在 self 上定义一个方法,但在 Python 中就没有那么容易了,是吗?

回答by ayaz

You should perhaps implement this by defining a custom manager for your class, and adding two manager methods on that manager (which I believe is the preferred way for adding table-level functionality for any model). However, another way of doing it is by throwing in two class methodson your class that query and return resulting objects, such as:

您或许应该通过为您的类定义一个自定义管理器并在该管理器上添加两个管理器方法来实现这一点(我认为这是为任何模型添加表级功能的首选方法)。但是,另一种方法是在您的类中加入两个类方法来查询和返回结果对象,例如:

class Status(models.Model):
    code = models.IntegerField()
    text = models.CharField(maxlength=255)

    @classmethod
    def successful(cls):
        return cls.objects.get(code=0)

    @classmethod
    def failed(cls):
        return cls.objects.get(code=1)

Do note please that get()is likely to throw different exceptions, such as Status.DoesNotExistand MultipleObjectsReturned.

请注意,这get()可能会引发不同的异常,例如Status.DoesNotExistMultipleObjectsReturned

And for an example implementation of how to do the same thing using Django managers, you could do something like this:

对于如何使用 Django 管理器执行相同操作的示例实现,您可以执行以下操作:

class StatusManager(models.Manager):
    def successful(self):
        return self.get(code=1)

    def failed(self):
        return self.get(code=0)

class Status(models.Model):
    code = models.IntegerField()
    text = models.CharField(maxlength=255)

    objects = StatusManager()

Where, you could do Status.objects.successful()and Status.objects.failed()to get what you desire.

在哪里,你可以做什么,Status.objects.successful()Status.objects.failed()得到你想要的。