在Django REST框架中序列化一对多关系

时间:2015-12-14 14:49:02

标签: python django django-rest-framework

我有两个班persontest,其中一个人可以进行多次测试。我尝试过序列化,但每次尝试使用

添加对象时
person= Person.objects.create(title="mr",name="name",address="address",city="city")

它会抛出错误 IntegrityError: NOT NULL constraint failed: appname_person.tests_id

models.py

class Test(models.Model):
    date = models.DateTimeField(auto_now_add=True)
    test_name = models.CharField(max_length=200,default='',blank=False)
    test_subject = models.CharField(max_length=100,default='')
    test_type = models.CharField(max_length=100,default='') 

    def __str__(self):
        return self.test_name

class Person(models.Model):
    tests = models.ForeignKey(Test)
    title = models.CharField(max_length=3,default="mr",blank=False)
    name = models.CharField(max_length=50,default='',blank=False)
    address = models.CharField(max_length=200,default='',blank=False)
    city = models.CharField(max_length=100,default='',blank=False)

    def __str__(self):
        return self.name

serializers.py

class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = Test
        fields = ('test_name','test_subject','test_type')

class PersonSerializer(serializers.ModelSerializer):

    tests = TestSerializer(many=True, read_only=True)
    class Meta:
        model = Person
        fields = ('id', 'title', 'name', 'address', 'city')

2 个答案:

答案 0 :(得分:4)

首先,你反过来说,测试应该有一个指向用户模型的外键。

class Person(models.Model):
    title = models.CharField(max_length=3,default="mr",blank=False)
    name = models.CharField(max_length=50,default='',blank=False)
    address = models.CharField(max_length=200,default='',blank=False)
    city = models.CharField(max_length=100,default='',blank=False)

    def __str__(self):
        return self.name


class Test(models.Model):
    tests = models.ForeignKey(Person)
    date = models.DateTimeField(auto_now_add=True)
    test_name = models.CharField(max_length=200,default='',blank=False)
    test_subject = models.CharField(max_length=100,default='')
    test_type = models.CharField(max_length=100,default='') 

    def __str__(self):
        return self.test_name

答案 1 :(得分:1)

序列化程序或数据层中的错误是?从您的代码看起来,您正在创建的对象是抛出错误,而不是序列化。

请试试这个

class Person(models.Model):
    tests = models.ForeignKey(Test, null=True)
    title = models.CharField(max_length=3,default="mr",blank=False)
    name = models.CharField(max_length=50,default='',blank=False)
    address = models.CharField(max_length=200,default='',blank=False)
    city = models.CharField(max_length=100,default='',blank=False)

    def __str__(self):
        return self.name

另请查看区别和use of null and blank

修改

我还可以看到另一个错误。您的ForeignKey是ManytoOne / OneToOne关系,这意味着您将一个人链接到测试。但是,在序列化程序中,您要使用many = True定义字段test。该序列化程序将期望ManyToMany字段。请调整序列化程序或

class PersonSerializer(serializers.ModelSerializer):

    tests = TestSerializer(read_only=True)
    class Meta:
        model = Person
        fields = ('id', 'title', 'name', 'address', 'city')

或调整您的模型

class Person(models.Model):
    tests = models.ManyToManyField(Test)
    title = models.CharField(max_length=3,default="mr",blank=False)
    name = models.CharField(max_length=50,default='',blank=False)
    address = models.CharField(max_length=200,default='',blank=False)
    city = models.CharField(max_length=100,default='',blank=False)

    def __str__(self):
        return self.name

编辑2:

如何向某人添加测试。我不确定您正在阅读哪些文档,但这是您应该如何做的。

test1 = Test(...)
test1.save()
test2 = Test(...)
test2.save()
test3 = Test(...)
test3.save()

person = Person(....)
person.save()
person.tests.add(test1, test2)
person.tests.add(test3)

请记住在添加测试之前保存此人,否则会抛出异常。必须这样做,因为ManyToMany关系必须知道要将测试链接到的person对象的id。 有关更多文档,请参阅this article