[英]How to add Token to a model that extends the User Model in Django Rest Framework?
I have the following to create a user and add a Token to it:我有以下内容来创建用户并向其添加令牌:
User = get_user_model()
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'password', 'first_name', 'last_name', 'email')
extra_kwargs = {'passwords': {'write_only': True, 'required': True}}
def create(self, validated_data):
user = User.objects.create_user(**validated_data)
token = Token.objects.create(user=user)
return user
I would like to be able to do the same thing for a Player:我希望能够为玩家做同样的事情:
class PlayerSerializer(serializers.ModelSerializer):
class Meta:
model = Player
fields = '__all__'
def create(self, validated_data):
# what to do here? How to create a new token for 'Player'?
I've tried this:我试过这个:
def create(self, validated_data):
player = Player.objects.create_user(**validated_data)
token = Token.objects.create(user=player)
return player
But got this error: TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use groups.set() instead.
但是得到了这个错误:
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use groups.set() instead.
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use groups.set() instead.
The Player model extends the 'MyUser' model: Player 模型扩展了“MyUser”模型:
class MyUser(AbstractUser):
pass
class Player(MyUser):
national_id = models.CharField(max_length=10)
def save(self, *args, **kwargs):
self.username = self.email
return super().save(*args, **kwargs)
I assume that you are using a payload similar to this:我假设您正在使用与此类似的有效负载:
{
"username": "root",
"password": "test",
"first_name": "a",
"last_name": "b",
"email": "a@b.com",
"national_id": "123",
}
Django's AbstractUser
comes with several fields not included in this payload (eg. is_staff
, is_superuser
), most of which come with either default arguments, or are allowed to be null. Django 的
AbstractUser
带有几个未包含在此有效负载中的字段(例如is_staff
、 is_superuser
),其中大多数带有默认参数,或者允许为空。
Because you specified fields = '__all__'
in your PlayerSerializer
, your endpoint is expecting every field to be present in the payload, hence your error.因为您在
PlayerSerializer
指定了fields = '__all__'
,您的端点期望负载中存在每个字段,因此您的错误。
If you were using a traditional model setup (by that I mean no inheritance), you would have received a helpful error message telling you exactly what's missing.如果您使用的是传统模型设置(我的意思是没有继承),您会收到一条有用的错误消息,告诉您到底缺少什么。 I suspect the model inheritance aspect part of your code broke the serializer early, resulting in an unhelpful message.
我怀疑您的代码的模型继承方面部分很早就破坏了序列化程序,从而产生了无用的消息。
Anyways, if my assumption is correct, you can fix this in 2 ways:无论如何,如果我的假设是正确的,您可以通过两种方式解决此问题:
include all of AbstractUser
's fields in your payload;在您的负载中包含
AbstractUser
的所有字段; see the source code for a full list查看完整列表的源代码
modify your serializer's meta to specify the fields you want.修改序列化程序的元数据以指定所需的字段。
eg:例如:
class PlayerSerializer(serializers.ModelSerializer):
class Meta:
model = Player
fields = (
'username',
'password',
'first_name',
'last_name',
'email',
'national_id',
)
def create(self, validated_data):
player = Player.objects.create_user(**validated_data)
token = Token.objects.create(user=player)
return player
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.