1. ホーム
  2. django

[解決済み] ChoiceFieldを使ったDjangoのRestフレームワーク

2022-10-17 19:01:08

質問

私はユーザーモデルに選択フィールドをいくつか持っており、Django Rest Framework にそれを実装する最善の方法を見つけようとしています。

以下は、私がやっていることを示すためのいくつかの簡略化されたコードです。

# models.py
class User(AbstractUser):
    GENDER_CHOICES = (
        ('M', 'Male'),
        ('F', 'Female'),
    )

    gender = models.CharField(max_length=1, choices=GENDER_CHOICES)


# serializers.py 
class UserSerializer(serializers.ModelSerializer):
    gender = serializers.CharField(source='get_gender_display')

    class Meta:
        model = User


# viewsets.py
class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

基本的に私がやろうとしていることは、get/post/putメソッドにコードの代わりに選択肢フィールドの表示値を使わせることで、以下のようなJSONになります。

{
  'username': 'newtestuser',
  'email': '[email protected]',
  'first_name': 'first',
  'last_name': 'last',
  'gender': 'Male'
  // instead of 'gender': 'M'
}

どうすればいいのでしょうか?上記のコードは動作しません。以前は、GETではこのようなものが動作していましたが、POST/PUTではエラーが発生しました。私はこれを行う方法についての一般的なアドバイスを探しています、それは一般的なもののように思えるが、私は例を見つけることができません。または私が何かひどく間違ったことをしているかのどちらかです。

どのように解決するのですか?

このスレッドの更新情報として、DRFの最新バージョンでは、実際に ChoiceField .

というわけで、もしあなたが display_name を返したいのであれば、サブクラス ChoiceField to_representation というメソッドを作ることです。

from django.contrib.auth import get_user_model
from rest_framework import serializers

User = get_user_model()

class ChoiceField(serializers.ChoiceField):

    def to_representation(self, obj):
        if obj == '' and self.allow_blank:
            return obj
        return self._choices[obj]

    def to_internal_value(self, data):
        # To support inserts with the value
        if data == '' and self.allow_blank:
            return ''

        for key, val in self._choices.items():
            if val == data:
                return key
        self.fail('invalid_choice', input=data)


class UserSerializer(serializers.ModelSerializer):
    gender = ChoiceField(choices=User.GENDER_CHOICES)

    class Meta:
        model = User

なので __init__ メソッドを変更したり、追加のパッケージを追加する必要はありません。