我的目标是接收一个JSON,其中包含创建用户所需的所有信息,以及将用于创建另一个对象的其他一些东西,这些都将使用最近创建的用户以及通过JSON。对于上下文,我的JSON当前如下所示:
{
"first_name": "John",
"last_name": "Doe",
"username": "newuser",
"email": "johndoe@hotmail.com",
"password": "somepassword",
"profile_image": null,
"type": 2
}
type
是创建用户不必要的信息。目前,我的自定义创建函数如下所示:
class UserSerializer(ModelSerializer):
class Meta:
model = User
fields = ['first_name', 'last_name', 'username', 'email', 'id', 'password', 'profile_image']
read_only_fields = ['id', 'created_at', 'updated_at', 'is_staff']
def create(self, validated_data):
new_user = User.objects.create_user(**validated_data)
types = self.request.data.get("type")
create_user_type = UserType.objects.create(user=new_user, type=types)
return create_user_type
查看Django Rest Framework文档,stackoverflow问题和调试后,它发生了很多变化。如果我按现在的方式运行代码,这就是我得到的:
AttributeError at /user/
'UserSerializer' object has no attribute 'request'
所以我认为发生这种情况是因为您无法通过执行self.request
来获得请求。我尝试将其创建到视图集中,因为我意识到那里的工作略有不同,但是随后发生了:
TypeError at /user/
create_user() argument after ** must be a mapping, not Request
我可以编辑问题以添加我忘记的任何信息。我还应该注意,无论错误如何,都会创建用户,但是我的目标是创建用户和另一个对象。我怎么能从自我中得到打字?
答案 0 :(得分:0)
简单地说,您无法从self
获得它,但是您可以从其他地方获得它。
如果您注意到第二个错误,则显示为
TypeError at /user/ create_user() argument after ** must be a mapping, not Request
这意味着在new_user = User.objects.create_user(**validated_data)
定义中,validated_data
是您要传递的Request
对象。
您可以尝试validated_data.get("type")
来获取类型!
免责声明:确保您的API安全。我对此还很陌生,不确定传递整个请求对象是否安全
编辑: 了解传递给函数的对象的数据类型将为您澄清很多事情。将代码块移至视图集之后,您是否更改了界面的方式?
编辑(2): 在这里回复您的评论:
types = self.request.data.get("type")
Request对象很可能具有反序列化的数据,这在Python中通常表示dict()
type
对象。这就是为什么可以在该对象上使用.get()
的原因(除非您将cls指定为一个钩子,以不同方式解释数据)。
这意味着,序列化JSON支持的数据类型(字符串,数字,列表/数组,JSON对象)在Python中将为str / bytes / unicode,int / float,list,dict。
因此,type(types)
实际上看起来像是int
。 (您说的是注释中的"2"
,对吗?在这种情况下,您的type(types)
应该给出str
)。
如果要在下一个命令中使用此值,则可能必须创建Types
类的对象,并将该值传递到其构造函数中(我不知道它的外观,只是一个猜测)
create_user_type = UserType.objects.create(user=new_user, type=types)
这应该可以解决您的问题,或者至少让您更好地理解它...
答案 1 :(得分:0)
在我看来,请求尚未定义。我希望可以在您的课程下看到导入或定义的方法。
在您的项目中四处寻找调用request()的其他类,然后看看您发现了什么。
答案 2 :(得分:0)
可以更优雅地解决这个问题。
class UserSerializer(ModelSerializer):
type = serializers.IntegerField(write_only=True, required=False) #optionl 'type' integer field
class Meta:
model = User
fields = ['first_name', 'last_name', 'username', 'email', 'id', 'password', 'profile_image', 'type']
read_only_fields = ['id', 'created_at', 'updated_at', 'is_staff']
def create(self, validated_data):
type = validated_data.pop('type')
user = super(UserSerializer, self).create(validated_data)
create_user_type = UserType.objects.create(user=user, type=type)
return user
UserSerializer不会返回UserType
对象。它将引发错误。
如果要与UserType
对象一起返回User
对象,则必须为Usertype
创建一个单独的序列化器,并将其用作嵌套在UserSerializer
中的序列化器。