1

My model:

  class SomeModel(models.Model):
       ...
    models.CharField(max_length=255, choices=BookPage.choices)**

My choices:

from enum import Enum


class BookPage(Enum):
    MAIN = "Main"
    SIDEBAR = "Sidebar"

    @property
    def choices(self):
        return [(key.value, key.name) for key in self]

I got this error Where I'm wrong?

choices' must be an iterable (e.g., a list or tuple).
D Malan
  • 10,272
  • 3
  • 25
  • 50
Alexx
  • 39
  • 3

2 Answers2

2

@d-malan is correct. When you call a property from a class instead of an instance, it will just return the property method instead of actually calling it. Using the @classmethod decorator will solve this.

Alternatively, if you are using a recent version of Django, you have two other options:

  • Use the poorly-documented classproperty decorator [https://docs.djangoproject.com/en/3.1/_modules/django/utils/functional/#classproperty].

  • Use the models.TextChoices class (which has a built-in choices method) [https://docs.djangoproject.com/en/3.1/ref/models/fields/#enumeration-types]

trubliphone
  • 4,132
  • 3
  • 42
  • 66
1

Your choices property is still an instance property so it won't give you your expected result when you call it on the BookPage class.

There doesn't seem to be an easy way to create properties on classes.

I'd suggest rather just using a classmethod, e.g.:

class BookPage(Enum):
    MAIN = "Main"
    SIDEBAR = "Sidebar"

    @classmethod
    def choices(cls):
        return [(key.value, key.name) for key in cls]

And call it as BookPage.choices().

D Malan
  • 10,272
  • 3
  • 25
  • 50