Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StatusModel is ALMOST compatible with Django 3.x TextChoices / IntegerChoices #509

Open
al-the-x opened this issue Nov 27, 2021 · 0 comments

Comments

@al-the-x
Copy link

al-the-x commented Nov 27, 2021

model_utils.add_status_query_managers used by StatusModel to attach QueryManager instances for each of the names in STATUS assumes that STATUS is either a model_utils.Choices or 2-tuple and ignores the choices_name value set on the status field of the StatusModel, if overridden:

for value, display in getattr(sender, 'STATUS', ()):

StatusModel could be made compatible with TextChoices / IntegerChoices if add_status_query_managers either:

  • Expected a possible TextChoices / IntegerChoices instance (e.g. by checking for choices on the STATUS model)
  • Respected the configured choices_name on the StatusField named status

There's a way to hack around it:

from django.db import models
from model_utils import models as extras

class SomeModel(extras.StatusModel):
    STATUSES = models.TextChoices("SomeModel.STATUSES", ("ONE", "TWO", "THREE"))

    STATUS = STATUSES.choices

    # status = extras.StatusField(choices=STATUS)  # implicit

But then we lose the convenience of comparisons between the value of status on a SomeModel instance and either SomeModel.STATUSES by name (e.g. instance.status is SomeModel.STATUSES.ONE) or SomeModel.STATUS, which is an unaddressed 2-tuple.

Ideally, we could use the new enum.Enum based API in Django 3.x AND get the benefits of StatusModel: status_changed timestamps and automatic custom managers for STATUS values just by leveraging the features of StatusField:

from django.db import models
from model_utils import models as extras

class SomeModel(extras.StatusModel):
    STATUS = models.TextChoices("SomeModel.STATUS", ("one", "two", "three"))

    status = extras.StatusField(choices_name="STATUS.choices")

    # one = model_utils.managers.QueryManager(status=STATUS.ONE)  # implicit
    # two = model_utils.managers.QueryManager(status=STATUS.TWO)  # implicit
    # three = model_utils.managers.QueryManager(status=STATUS.THREE)  # implicit

Setting choices_name to STATUS.choices appears to satisfy StatusField -- no error is raised trying to set choices on the field instance -- but add_status_query_managers raises trying to unpack the name and value from STATUS, since it's an enum.Enum and not a 2-tuple or model_extras.models.Choices instance.

As a receiver function add_status_query_managers seems to accept the model class as sender and perform operations on it, so I think we could modify it to at least respect the choices_name of the StatusField. I'm not sure that will address my stated desire to compare status to values of STATUS, TBH, but I'm willing to write a patch to test it out.

@al-the-x al-the-x changed the title StatusModel is ALMOST compatible with Django 3.x TextChoices / IntChoices StatusModel is ALMOST compatible with Django 3.x TextChoices / IntegerChoices Nov 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant