【发布时间】:2017-03-22 06:35:45
【问题描述】:
注意:这并不是真正让 Django 的中间模型用于具有额外字段的多对多关系。这是关于如何将 Django Rest Framework 的 Serializers.ModelSerializer 与中间模型一起使用。 我有这些模型(以及更多):
class Method(models.Model):
name = models.CharField(max_length=50, unique=True)
descripton = models.TextField(null=False)
class Version(models.Model):
version_number = models.CharField(max_length=50)
cmd_line_script = models.CharField(max_length=250, null=False)
SOP = models.TextField(null=False)
FK_method = models.ForeignKey(Method, on_delete=models.CASCADE)
class Meta:
unique_together = ('version_number', 'FK_method')
class Instrument(models.Model):
serial_number = models.CharField(max_length=50, unique=True)
asset_number = models.CharField(max_length=50, unique=True)
name = models.CharField(max_length=50)
checksum_string = models.CharField(max_length=128, null=True)
FK_instr_type = models.ForeignKey(InstrType, related_name='installations', on_delete=models.PROTECT)
Instr_Version = models.ManyToManyField(
Version,
through='Instr_Version',
related_name = 'Instr_Version',
)
class Instr_Version(models.Model):
FK_version = models.ForeignKey(Version, on_delete=models.CASCADE)
FK_instrument = models.ForeignKey(Instrument, on_delete=models.CASCADE)
validating_user = models.ForeignKey(UserProfile, on_delete=models.PROTECT)
timestamp = models.DateField(auto_now_add=True)
class Meta:
unique_together = ('FK_version', 'FK_instrument')
他们很好。我正在尝试使用[Django-Rest-Framework serializers][1] 通过 Instr_Version 表进行序列化,以便 api 可以检索被列为对该仪器有效的所有版本(及其 FK_method 数据,通过 MethodSerializer)的 json 表示。
到目前为止,我有这些序列化程序(还有一些用于 InstrType、UserProfile 等)
class MethodSerializer(serializers.ModelSerializer):
class Meta:
model = Method
fields = ('id', 'name', 'description', 'version_set')
class VersionSerializer(serializers.ModelSerializer):
method = MethodSerializer(read_only=True)
#Instr_Version = Instr_VersionSerializer(source='Instr_Version_set', many=True, read_only=True)
class Meta:
model = Version
fields = ('id', 'method', 'version_number', 'cmd_line_script', 'SOP')
class Instr_to_VersionSerializer(serializers.ModelSerializer):
version = VersionSerializer(source='FK_version_id', read_only=True, many=False)
validator = UserProfileSerializer(source='validating_user', read_only=True)
class Meta:
model = Instr_Version
fields = ('id', 'version', 'validator', 'timestamp')
class InstrumentSerializer(serializers.ModelSerializer):
instr_type = InstrTypeSerializer(source='FK_instr_type', read_only=True)
Validated_Versions = Instr_to_VersionSerializer(source='Instr_Version', many=True, read_only=True)
class Meta:
model = Instrument
fields = ('id', 'asset_number', 'serial_number', 'name', 'checksum_string', 'instr_type', 'Validated_Versions')
我得到的最接近的是 GET,例如:“api/getInstrument/?asset_number=1234” 结果:
{
"id": 11,
"asset_number": "1234",
"serial_number": "1234",
"name": "Instrument1",
"checksum_string": "0123456789ABCDEF0123",
"instr_type": {
"id": 70,
"make": "Make1",
"model": "Model1",
"service_email": "model1@company.com",
"service_website": "www.model1.com"
},
"Validated_Versions": [{
"id": 9
}, {
"id": 10
}, {
"id": 12
}]
}
这很不错,但是validated_versions 数组应该包含比“id”更多的数据。
为了实验,我尝试从Instr_to_VersionSerializer 和VersionSerializer 的字段列表中添加/删除id。证据表明Instr_to_VersionSerializer 内的字段列表中的id 实际上是在Instr_Version 模型(或版本模型上的PK)上打印FK_version_id,而不是像我预期的那样打印Instr_Version 的PK。这让我觉得 DJR 是“自动”通过多对多直接看到 Version 模型,所以我尝试将 Instr_to_VersionSerializer 更改为:
class Instr_to_VersionSerializer(serializers.ModelSerializer):
#version = VersionSerializer(source='FK_version_id', read_only=True, many=False)
validator = UserProfileSerializer(source='validating_user', read_only=True)
#method = MethodSerializer(read_only=True)
class Meta:
model = Instr_Version
fields = ('id', 'version_number', 'cmd_line_script', 'SOP', 'validator', 'timestamp')
这将使 VersionSerializer 完全脱离它,但我收到 Field nameversion_numberis not valid for modelInstr_Version. 错误,所以我不确定发生了什么。
我自己的最后一次尝试是将version = VersionSerializer 的source 更改为versions,这是相反的关系。这似乎不合逻辑,但我当时正在尝试任何事情。结果是:version_number 不是有效字段的错误,这告诉我我终于到达了VersionSerializer,所以我注释掉了VersionSerializer 中的大部分字段,只是为了看看发生了什么,但这只是导致:
"Validated_Versions":[{"id":9,"version":{}},{"id":10,"version":{}},{"id":12,"version":{}}]
【问题讨论】:
标签: django rest serialization django-rest-framework many-to-many