Django rest IntegrityError:1048,外键序列化器上的“列不能为空”

时间:2018-05-08 06:28:10

标签: django django-rest-framework

我的模型定义如下:

class Responsibility(models.Model):
    name = models.CharField(max_length=50, blank=True, null=True, )

class Collaborator(models.Model):
    name = models.CharField(max_length=50, blank=True, null=True, )


class Card(models.Model):
    thing = models.CharField(max_length=50, blank=True, null = True, )
    responsibilities = models.ForeignKey(Responsibility, related_name='res_cards', blank=True, on_delete=models.CASCADE)
    collaborators = models.ForeignKey(Collaborator, related_name='col_cards', blank=True, on_delete=models.CASCADE)

序列化器:

class CollaboratorSerializer(serializers.ModelSerializer):

    class Meta:
        model = Collaborator
        fields = '__all__'

class ResponsibilitySerializer(serializers.ModelSerializer):
    class Meta:
        model = Responsibility
        fields = '__all__'      


class CardSerializer(serializers.ModelSerializer):
    responsibilities = ResponsibilitySerializer(many=True,)
    collaborators = CollaboratorSerializer(many=True,)

    class Meta:
        model = Card
        fields = '__all__'

    def create(self, validated_data):
        responsibilities_data = validated_data.pop('responsibilities')
        collaborators_data = validated_data.pop('collaborators')

        card = Card.objects.create(**validated_data)
        for responsibility_data in responsibilities_data:
            Responsibility.objects.create(card=card, **track_data)
        for collaborator_data in collaborators_data:
            Collaborator.objects.create(card=card, **track_data)
        return card

我的POST请求如下所示:

{u'thing': u'Book', u'responsibilities': [{u'name': u'Name'}, {u'name': u'ISBN'}], u'collaborators': [{u'name': u''}]}

但应用程序抛出错误。我错过了什么?责任和合作者不会预先存在,它们将与卡一起创建,也应与卡一起更新,而不是独立更新。

更新:我对GET和POST的看法

@api_view(['GET', 'POST'])
def card_list(request):
    """
    List all tasks, or create a new card
    """
    if request.method == 'GET':
        cards = Card.objects.all()
        serializer = CardSerializer(cards, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
        print(request.data)
        serializer = CardSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(
                serializer.errors, status=status.HTTP_400_BAD_REQUEST)

2 个答案:

答案 0 :(得分:1)

此处可能会出现错误:card = Card.objects.create(**validated_data) - 当您尝试创建Card条目时; Django期望ResponsbilityCollaborator外键作为validated_data的一部分出现。这是因为您的架构的定义方式;外键不是nullabe;因此,如果没有两个Card条目,则无法创建ForeignKey。 将Card模型更改为responsibilitiescollaborators

的空值
class Card(models.Model):
    thing = models.CharField(max_length=50, blank=True, null = True, )
    responsibilities = models.ForeignKey(Responsibility, related_name='res_cards', blank=True, null=True, on_delete=models.CASCADE)
    collaborators = models.ForeignKey(Collaborator, related_name='col_cards', blank=True, null=True, on_delete=models.CASCADE)

如果不能更改架构;在create方法中颠倒您的操作顺序:

for responsibility_data in responsibilities_data:
    resp = Responsibility.objects.create(**responsibility_data)
for collaborator_data in collaborators_data:
    collab = Collaborator.objects.create(**collaborator_data)
validated_data.update({responsibilities: resp.pk, 'collaborators': collab.pk})
card = Card.objects.create(**validated_data)

从您的问题来看,您似乎需要将单张卡与多个职责和协作者相关联。您应该将外键移动到其他表(resp和collllab)以指向卡片,而不是从卡片向前指向。

答案 1 :(得分:0)

也可以在外键上设置null=Trueblank=True

class Card(models.Model):
    thing = models.CharField(max_length=50, blank=True, null = True, )
    responsibilities = models.ForeignKey(Responsibility, related_name='res_cards', blank=True,null=True on_delete=models.CASCADE)
    collaborators = models.ForeignKey(Collaborator, related_name='col_cards', blank=True, null=True on_delete=models.CASCADE)