我是Django的新手,我试图将Unit和current_user外键保存在基于数据库的pk中,但每次尝试这样做时,都会遇到两种错误类型serializers.is_valid()
引发异常错误或序列化程序返回"Invalid data. Expected a dictionary, but got Unit."
我尝试通过摆脱绕过序列化程序的方式非常丑陋,但我得到ee8452a4-2a82-4804-a010-cf2f5a41e006必须是SavedUnit.unit的实例。我还尝试过直接使用{{ 1}}没有运气
model.py
SavedUnit.objects.create()
serializers.py
class SavedUnit(models.Model):
"""
Saving units for later models
relationship with units and users
"""
id = models.UUIDField(primary_key=True, default=hex_uuid, editable=False)
unit = models.ForeignKey(Unit, on_delete=models.CASCADE)
user = models.ForeignKey('accounts.User', on_delete=models.CASCADE, related_name='user')
published_at = models.DateTimeField(auto_now_add=True)
views.py
class SavedSerializer(serializers.ModelSerializer):
unit = UnitSerializer()
class Meta:
model = SavedUnit
fields = [
'id',
'unit'
]
答案 0 :(得分:0)
实际上问题出在这里:
def post(request, pk):
if request.user.is_authenticated:
unit = get_object_or_404(Unit, id=pk)
serializers = SavedSerializer(data=unit) <-- Here
您正在传递单元实例,但它应该是request.data,如下所示:
serializers = SavedSerializer(data=request.data)
(我不确定您在做什么,如果您已经拥有PK,那为什么还要使用序列化器呢?因为您已经拥有单元,所以不需要它,并且您可以从{{ 1}},您已经在这样做了。我认为您不应该使用request.user
,可以这样声明post方法:@staticmethod
并删除静态方法装饰器)
答案 1 :(得分:0)
您的代码仅将序列化程序用于验证,但是可以使用它在调用serializer.save()
的数据库上插入或更新新对象。
要使用django-rest-framework保存外键,必须在序列化器上放置一个相关字段以进行处理。使用PrimaryKeyRelatedField
。
serializers.py
class SavedSerializer(serializers.ModelSerializer):
unit_id = serializers.PrimaryKeyRelatedField(
source='unit',
queryset=Unit.objects.all()
)
unit = UnitSerializer(read_only=True)
class Meta:
model = SavedUnit
fields = [
'id',
'unit_id',
'unit'
]
views.py
class SavedUnitView(APIView):
permission_classes = (permissions.IsAuthenticated,) # For not handling authorization mannually
def post(request):
serializer = SavedSerializer(data=request.data)
serializer.is_valid(raise_exception=True) # Trigger Bad Request if errors exist
serializer.save(user=request.user) # Passing the current user
return Response(serializer.data, status=status.HTTP_201_CREATED)
现在,单元的ID将像这样在请求正文中传递
POST /saved-units/
Accept: application/json
Content-Type: application/json
Authorization: Token your-api-token
{
"unit_id": 5 # Id of an existing Unit
}