起初,我有这个序列化器,它对GET
和POST
工作得很好(创建新条目)
class DrawingSerializer(ModelSerializer):
drawing = serializers.FileField()
detail = serializers.JSONField()
class Meta:
model = m.Drawing
fields = ('id','detail','drawing','user','created_at','updated_at')
在创建条目的视图集中。
class DrawingViewSet(viewsets.ModelViewSet):
queryset = m.Drawing.objects.all()
serializer_class = s.DrawingSerializer
def create(self, request, *args, **kwargs):
request.data['user'] = request.user.id #set userid
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer) # it makes the new entry with user
return Response(serializer.data)
和models.py
class CustomUser(AbstractUser):
detail = models.JSONField(default=dict,null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Drawing(models.Model):
drawing = f.FileField(upload_to='uploads/')
detail = models.JSONField(default=dict)
user = models.ForeignKey(CustomUser,on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
在这种情况下,user
是外键模型。
所以我想得到用户的名字,电子邮件等等,然后我像这样修改了Serializer
。
class DrawingSerializer(ModelSerializer):
drawing = serializers.FileField()
detail = serializers.JSONField()
user = CustomUserSerializer(read_only=True) # change here
class Meta:
model = m.Drawing
fields = ('id','detail','drawing','user','created_at','updated_at')
它也适用于get
。我可以从CustomUser
模型中获取数据为user
。
但是,当POST(creating)
时,它显示错误
django.db.utils.IntegrityError:(1048,“列'user_id'不能为null”)
为什么会发生这种情况,user_id是什么?
”张云的回答是。
我在下面这样更新,
但是,它不会在响应中显示user_data
或user
。(我认为user
是正确的,虽然没有显示)
class DrawingSerializer(ModelSerializer):
drawing = serializers.FileField()
detail = serializers.JSONField()
user_data = CustomUserSerializer(read_only=True) # change here
class Meta:
model = m.Drawing
fields = ('id','detail','drawing','user','user_data', 'created_at','updated_at')
extra_kwargs = {"user": {"write_only": True}}
2条答案
按热度按时间k3bvogb11#
当你将
ForeignKey
添加到模型中时,Django会在数据库中创建FKFIELD_id
字段。在您的问题中,您将user
设置为read_only
字段。因此,您无法将user
字段传递给序列化程序,并且您会得到database
错误。最简单的方法是拆分
user
和user_data
mwg9r5ms2#
所以你在这里所做的被称为嵌套序列化器,在这种情况下,你使用
CustomUserSerializer
序列化User
对象来获取它的属性,这就是当你调用GET
方法时发生的事情。但是当你尝试通过调用
POST
方法创建Drawing
对象时,Django会阻止user
值,即使你在请求数据中发送了它,因为你已经定义了read_only=True
。这就引出了这个错误django.db.utils.IntegrityError:(1048,“列'user_id'不能为null”)
这基本上告诉你,你有一个字段名为
user
在Drawing
模型-这是一个外键-它不能为空,我需要的主键,这是user
的id
模型。**第一种解决方案:**只需删除
read_only=True
,并确保在创建新的Drawing
对象时将user
字段包含在请求数据中。**第二种解决方案:**在你的序列化器中创建两个不同的属性,一个用于阅读,一个用于写,例如:
**第三种方案:**覆盖序列化器的create方法,在保存
Drawing
对象之前手动设置user
字段。这允许您在序列化器中将user
字段保留为read-only
,但在创建对象时仍然提供值,例如: