21

私は Django レルムに不慣れですが、そこにはたくさんの「魔法」があることがわかります。Django REST Framework を使用して、無料のユーザー登録を可能にするアプリを作成しています。私のユーザーは、Django ユーザーでは利用できないいくつかの追加フィールドを必要としています。だから私はユーザーを拡張するためにググった。このようなものを作成することでこれを行う必要があるという考えがあります

class MyUser(models.Model):
    user = models.ForeignKey(User, unique=True)
    city = models.CharField(max_length=50, blank=True, default='')

これは問題ありませんが、このシリアライザーがあります

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyUser
        fields = ('id', 'username', 'password', 'first_name', 'last_name', 'email', 'city')

したがって、問題は、このシリアライザーがここで「魔法」を行うことです。モデルに必要なフィールドを見つけようとします...ここにリストされているフィールドを持つユーザーが必要です。これらのフィールドはユーザーにあり、「都市」は新しいカスタムフィールドです。シリアライザーは、ユーザー モデル内を参照する必要があることを理解していません。

ここで何が欠けていますか?User内にいくつかのフィールドが必要であることをこのシリアライザに伝えるには? ユーザーも作成できる必要があります。

4

6 に答える 6

20

したがって、回答の下にコメントを投稿するのに十分な評判がないようです。しかし、Kevin Stone が説明したことを詳しく説明すると、モデルが次のようなものである場合:

class AppUser(models.Model):
    user = models.OneToOneField(User)
    ban_status = models.BooleanField(default=False)

次のようにして、カスタム ユーザーと django ユーザーの両方を作成できます。

class AppUserSerializer(serializers.ModelSerializer):
    username = serializers.CharField(source='user.username')
    email = serializers.CharField(source='user.email')
    password = serializers.CharField(source='user.password')
    ban_status = serializers.Field(source='ban_status')

    class Meta:
        model = AppUser
        fields = ('id', 'username', 'email', 'password', 'ban_status')

    def restore_object(self, attrs, instance=None):
        """
        Given a dictionary of deserialized field values, either update
        an existing model instance, or create a new model instance.
        """
        if instance is not None:
            instance.user.email = attrs.get('user.email', instance.user.email)
            instance.ban_status = attrs.get('ban_status', instance.ban_status)
            instance.user.password = attrs.get('user.password', instance.user.password)
            return instance

        user = User.objects.create_user(username=attrs.get('user.username'), email= attrs.get('user.email'), password=attrs.get('user.password'))
        return AppUser(user=user)
于 2014-10-29T03:24:30.060 に答える
16

さて、いくつかのこと。OneToOneFieldユーザー モデル拡張用に を作成します。

class MyUser(models.Model):
    user = models.OneToOneField(User)
    city = models.CharField(max_length=50, blank=True, default='')

さて、Django Rest Framework の強みは、シリアライザーを構築して、シリアライズ時にこれらのモデルの両方からデータを取得できることです。

class UserSerializer(serializers.ModelSerializer):
    city = serializers.CharField(source='myuser.city')
    class Meta:
        model = User
        fields = ('id', 'username', 'password', 'first_name', 'last_name', 'email', 'city')

restore_object()最後に、ユーザーを作成する場所では、カスタム フィールドを使用しているため、入力データから両方のモデルを構築する独自のフィールドを実装する必要があります。

また、Django でのユーザーの作成は少し異なります。create_user()ハッシュ化されたパスワードを呼び出して提供する必要があるため、シリアライザーからフィールドを格納するほど単純ではありません。

于 2013-11-06T08:01:50.523 に答える
3

このユースケースがドキュメントで見つけやすくなればいいと思います。@jamod が指摘したように、DRF 3 では、ここで見つけることができます。

class UserSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer()

    class Meta:
        model = User
        fields = ('username', 'email', 'profile')

    def create(self, validated_data):
        profile_data = validated_data.pop('profile')
        user = User.objects.create(**validated_data)
        Profile.objects.create(user=user, **profile_data)
        return user
于 2017-01-12T15:24:49.310 に答える
2

Django Rest Framework を使用する場合は注意が必要です。カスタム ユーザー モデルは、組み込みのトークン認証を利用できません。それができるようになるまでは、カスタム モデルでユーザーに対して OneToOneField を使用することをお勧めします。カスタム モデルには、保持したい追加のフィールドが含まれます。1 対 1 では、カスタム ユーザーからユーザーへのアクセスと、ユーザーからのカスタム ユーザーへのアクセスが提供されます。

于 2013-11-06T01:55:56.310 に答える