Use models utils.Choices conveniently TIPS

model_utils.Choices

Django, DRF users Do you use model_utils.Choices? We use it conveniently, but basically we often use it for status management.

Is it like this?

class News(models.Model):
    STATUS = Choices(
        ('DRAFT',     'draft'),
        ('CHECK',     'Waiting for review'),
        ('PUBLISHED', 'Release'),
    )

    status = StatusField(
        choices_name='STATUS',
        help_text="Status",
        default=STATUS.DRAFT,
    )

    title = models.CharField(
        max_length=1024,
        null=False,
        blank=False,
        default="",
        help_text="News title"
    )

    body = models.TextField(
        null=False,
        blank=False,
        default="",
        help_text="News details"
    )

What is the explanation (VALUE) of Choice used for?

You can define the KEY and its description in Choice (the KEY is stored in the DB), but I'm not sure how to use this description. Isn't it okay to comment? I feel like. Moreover, if this Choice field is output as it is with Serializer, only KEY will be output, so there is no way to use the explanation (VALUE).

How to use VALUE

For example, in the example of ↑, if there is a management screen that manages news, you may want to display the status in the list or search by status. On that screen, you want to use Draft orPublicinstead of DRAFT or PUBLISHED.

At such times, it seems stupid to implement each programmer to return KEY and VALUE in the output serialization of Choice, so we are creating and operating such an extension.

class MyChoiceField(serializers.ChoiceField):
    def to_representation(self, obj):
        choice = getattr(self, '_choices')
        key = str(obj)
        if key in choice:
            return {'key': key, 'val': choice[key]}
        else:
            return {'key': key, 'val': ''}


class MyModelSerializer(serializers.ModelSerializer):
    """
Rewrite fields that are automatically expanded to serializer
    """
    serializer_choice_field = MyChoiceField

Each serializer inherits from MyModelSerializer.

class NewsSerializer(MyModelSerializer):
    class Meta:
        model = News
        fields = "__all__"

Now status will output key and value.

Recommended Posts

Use models utils.Choices conveniently TIPS
Use prefetch_related conveniently with Django
Pandas / DataFrame Tips for practical use