这是错误的示例:
型号:
from django.db import models
class Hero(models.Model):
alias = models.(max_length=60)
character = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.name
序列化器:
class HeroSerializer(serializers.ModelSerializer):
character = HyperlinkedRelatedField(read_only=True, default=<some user object>)
class Meta:
model = Hero
fields = ('character', 'alias')
视图集:
class HeroViewSet(NestedViewSetMixin,
mixins.CreateModelMixin,
mixins.UpdateModelMixin,
viewsets.ReadOnlyModelViewSet):
queryset = Hero.objects.all()
serializer_class = HeroSerializer
测试:
def test_created_successfully(self):
alias = 'blab blah'
response = self.client.post(self.url, {'name': name})
self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.data)
现在通过的测试是drf 3.7.7
当我升级到 drf 3.8.2 时,这个错误开始发生
django.db.utils.IntegrityError: null value in column "character_id" violates not-null constraint
DETAIL: Failing row contains (blah_blah, null).
他们说现在默认 + read_only 字段被排除在可写字段之外,因此您必须通过编写 Perform_create 或重写序列化器的 create 、 update 和 save 函数来显式保存这些字段
所以我在视图集中写了这个
def perform_create(self, serializer):
serializer.save(character=<some user object>)
供参考,这个 perfrom_create 在 mixins.CreateModelMixin 的 create 方法中被调用
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
所以它在这里工作,但现在如果相同的序列化器更改为(字符字段更改为名称,并且名称的源为“字符字段”。
class HeroSerializer(serializers.ModelSerializer):
name = HyperlinkedRelatedField(source='character', read_only=True, default=<some user object>)
class Meta:
model = Hero
fields = ('name', 'alias')
我的测试失败了
self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.data)
AssertionError: 400 != 201 : {'character': [ErrorDetail(string='This field is required.',
code='required')]}
这个测试在创建函数的下面一行中失败,即这甚至没有达到我重写的perform_create。
serializer.is_valid(raise_exception=True)
数据无效。
需要帮助。
在这种情况下必须使用
allow_null
的 HyperlinkedRelatedField
参数。