我一直在努力在 django 序列化程序中添加多对多关系,而不是通过视图访问。
我在模型文件“MODISLevel1”和“FileProperties”中创建了 2 个类。其中 MODISLevel1 有一个名为“filesProperties”的字段,指向“FileProperties”类。
模型看起来像:
class FileProperties(models.Model):
FileName = models.CharField(blank=True, max_length=1000)
FileID = models.CharField(blank=True, max_length=1000)
FileSize = models.CharField(blank=True, max_length=1000)
Updated = models.CharField(blank=True, max_length=1000)
GeoBox = models.CharField(blank=True, max_length=1000)
def __str__(self):
return self.FileName
class Meta:
ordering = ('FileName',)
class MODISLevel1(models.Model):
ProductLevel = models.CharField(max_length=7,
choices=ProductLevelsChoices,
default='MOD03')
SpacecraftType = models.CharField(max_length=5,
choices=SpacecraftTypeChoices,
default='Terra')
StartTimespan = models.TextField()
EndTimespan = models.TextField()
AOI = models.TextField()
DegreeNumbers = models.TextField()
filesProperties = models.ManyToManyField(FileProperties)
def __str__(self):
return self.ProductLevel
class Meta:
ordering = ('ProductLevel',)
至于我检查的序列化程序http://django-rest-framework.org/api-guide/relations.html#nested-relationships它告诉嵌套关系应该以下列方式创建:
class FilePropertiesSerializer(serializers.ModelSerializer):
class Meta:
model = FileProperties
fields = ('id', 'FileName', 'FileID', 'FileSize', 'Updated', 'GeoBox')
class MODISLevel1Serializer(serializers.ModelSerializer):
filesProperties = FilePropertiesSerializer(many=True)
class Meta:
model = MODISLevel1
fields = ('id', 'ProductLevel', 'SpacecraftType', 'StartTimespan', 'EndTimespan', 'AOI', 'DegreeNumbers', 'filesProperties')
对于视图文件,我尝试了不同的方法使其工作但没有成功。
1-从模型“MODISLevel1”创建一个实例,填充其字段,保存它,然后通过迭代填充 m2m 字段:
modisLevel1 = MODISLevel1()
modisLevel1.ProductLevel = productLevel
modisLevel1.SpacecraftType = spacecraftType
modisLevel1.StartTimespan = startTimespan
modisLevel1.EndTimespan = endTimespan
modisLevel1.AOI = AOI
modisLevel1.DegreeNumbers = degreeNumbers
modisLevel1.save()
#Inside a loop
f = FileProperties()
f.FileID = fileID
f.FileName = fileName
f.Updated = updated
f.GeoBox = geoBox
f.FileSize = fileSize
f.save()
modisLevel1.filesProperties.add(f)
serializer = MODISLevel1Serializer(data=modisLevel1)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
我得到的错误是:{“non_field_errors”:[“无效数据”]},但是当我执行保存命令“modisLevel1.save()”时,它肯定被添加到数据库中,但这不是我需要的。
2-创建一个 json 文件并通过迭代将“filesProperties”附加到它:
jsonFile = {u"ProductLevel": productLevel, u"SpacecraftType": spacecraftType, u"StartTimespan": startTimespan,
u"EndTimespan":endTimespan, u"AOI": AOI, u"DegreeNumbers": u"POINT(22.5,28.34) POINT(28.64,28.34) POINT(29.4,19.16) POINT(19.19,19.3067)",
u"filesProperties": [] }
#inside the loop
jsonFile["filesProperties"].append({u"FileName":fileName, u"FileID":fileID, u"FileSize":fileSize, u"Updated":updated, u"GeoBox":geoBox})
serializer = MODISLevel1Serializer(data=jsonFile)
这会引发一个错误,即基本模型在设置 m2m 字段之前必须有一个值:无法添加“”:实例在数据库“默认”上,值在数据库“无”上
3-创建一个dict并将模型解析为这个字典,然后将FileProperties转换为字典并将其附加到先前创建的字典中:
modisLevel1 = MODISLevel1()
modisLevel1.ProductLevel = productLevel
modisLevel1.SpacecraftType = spacecraftType
modisLevel1.StartTimespan = startTimespan
modisLevel1.EndTimespan = endTimespan
modisLevel1.AOI = AOI
modisLevel1.DegreeNumbers = degreeNumbers
modisLevel1.save()
dict = model_to_dict(modisLevel1)
#FIXME!
dict['filesProperties'] = [{"FileName": "fileName", "FileID": "fileID", "FileSize": "fileSize", "Updated": "updated", "GeoBox": "geoBox"},
{"FileName": "fileName", "FileID": "fileID", "FileSize": "fileSize", "Updated": "updated", "GeoBox": "geoBox"},
{"FileName": "fileName", "FileID": "fileID", "FileSize": "fileSize", "Updated": "updated", "GeoBox": "geoBox"}]
serializer = MODISLevel1Serializer(data=dict)
这个抛出与前一个相同的错误。
我确实检查了一些可能接近这个问题的其他帖子,但没有一个对我有用: django rest nested relationship in post/put
我的 json 发布请求如下所示:
[
{
"ProductLevel": "MOD03",
"SpacecraftType": "Terra",
"StartTimespan": "2013.11.02",
"EndTimespan": "2013.11.02",
"AOI": "swath",
"DegreeNumbers": "POINT(22.5,28.34) POINT(28.64,28.34) POINT(29.4,19.16) POINT(19.19,19.3067)"
}
]
请注意,在“view.py”文件中,我可以将值存储在数据库中,但如果我绕过序列化程序,就像我上面显示的示例一样。
那么有人遇到过同样的问题并且知道如何解决这个问题吗?将不胜感激!