LoginSignup
1
1

More than 3 years have passed since last update.

models_utils.Choices を便利につかう TIPS

Posted at

model_utils.Choices

Django, DRFをお使いの皆さん model_utils.Choices って使ってますか?
僕たちは便利に使っているのですが、基本的にはステータス管理でよく使います。

こんな感じですかね。

class News(models.Model):
    STATUS = Choices(
        ('DRAFT',     '下書き'),
        ('CHECK',     'レビュー待ち'),
        ('PUBLISHED', '公開'),
    )

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

    title = models.CharField(
        max_length=1024,
        null=False,
        blank=False,
        default="",
        help_text="ニュースタイトル"
    )

    body = models.TextField(
        null=False,
        blank=False,
        default="",
        help_text="ニュースの詳細"
    )

Choiceの説明(VALUE)って何に使うんだろう?

ChoiceではKEYとその説明を定義出来る(DBにはKEYが保存されている)のですが、この説明をどう使うと便利なのかって良く分からなかったりします。コメントで良いじゃん?って感じです。かつ、このChoiceフィールドはSerializerでそのまま出力するとKEYだけが出力されるので、さらに説明(VALUE)の使いみちがありません。

VALUEの使いみち

例えば、↑の例で説明すれば、ニュースを管理する管理画面があるとして、その一覧ではステータスを表示したり、ステータス毎に検索したい事があると思います。その画面で DRAFTPUBLISHED ではなく、 下書き とか 公開中 とかで使いたいですよね。

そういう時に各プログラマがChoiceの出力シリアライズでKEYとVALUEを返すように都度実装するのはバカらしいので、僕たちはこんな拡張を作って運用しています。

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):
    """
    シリアライザに自動展開されるフィールドを書き換え
    """
    serializer_choice_field = MyChoiceField

各シリアライザは MyModelSerializer を継承します。

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

これで status は key, valueが出力されるようになります。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1