继承Django选择class来扩展它?

Inherit Django choice class to extend it?

我的 models.py 中有一个字段接受 class 中确定的选择:

from apps.users.constants import UserChoices


class User(models.Model):
    choices = models.CharField(max_length=10, blank=True, choices=UserChoices.choices(), default=UserChoices.PUBLIC_USER)

选择class是这样的:

from django.utils.translation import ugettext_lazy as _


class UserChoices:
    PRIVATE_USER = "private_user"
    PUBLIC_USER = "public_user"

    @classmethod
    def choices(cls):
        return (
            (cls.PRIVATE_USER, _("Private User")),
            (cls.PUBLIC_USER, _("Public User")),
        )

我的疑问是如何将此 UserChoices class 继承到另一个选择 class,以便使用其他选项扩展它。

我尝试了以下方法:

class ExtendedChoices(UserChoices):

    OTHER_CHOICE = "other_choice"

    @classmethod
    def choices(cls):
        return (
            UserChoices.choices(),
            (cls.OTHER_CHOICE, _("Other choice")),
        )

但是它给我一个迁移错误:

users.OtherModel.other_choice: (fields.E005) 'choices' must be an iterable containing (actual value, human readable name) tuples.

显然这个例子是简化的,实际代码在原始代码中有 40 多个选择 class,在扩展代码中有 20 多个选择。

您需要从 parent 中解压这些文件。您可以使用 星号 (*):

class ExtendedChoices(UserChoices):

    OTHER_CHOICE = "other_choice"

    @classmethod
    def choices(cls):
        return (
            *UserChoices.choices(),  # ← an asterisk to unpack the tuple
            (cls.OTHER_CHOICE, _("Other choice")),
        )

如果我们在另一个元组中解包一个元组,我们将构造一个元组,其中包含解包元组的所有项目作为新元组的元素。例如:

>>> x = (1,4,2)
>>> (x, 5)
((1, 4, 2), 5)
>>> (*x, 5)
(1, 4, 2, 5)

如果我们因此不使用星号,它只会将 x 视为一个元组,因此我们构造一个二元组,并将元组 x.[=17 作为第一个元素=]

如果我们解压第一个元组,我们将获得一个 4 元组,其中前三个元素来自 x,然后是 5