在 django 4.2 中,我有一个具有特殊属性的模型。
它是一个 JSONField,它是一个像这样的列表:
Practitioner.objects.create(
name="Aldridge, Elizabeth Jane",
specialties = [
{
"type": "CFPC Specialist",
"issued_on": "Effective:18 May 2009",
"specialty": "Family Medicine"
},
{
"type": "RCPSC Specialist",
"issued_on": "Effective:30 Jun 2019",
"specialty": "Anesthesiology"
}
]
可能有 0 名成员或超过 2 名成员。
这是我的查询:
practitioners = Practitioner.objects.filter(specialties__0__specialty = "Anesthesiology")
我想搜索除第 0 个专业之外的所有专业成员。
我已经测试了这个不正确的查询:
practitioners = Practitioner.objects.filter(specialties__each__specialty = "Anesthesiology")
practitioners = Practitioner.objects.filter(specialties__any__specialty = "Anesthesiology")
practitioners = Practitioner.objects.filter(specialties__all__specialty = "Anesthesiology")
我在 django 文档中没有找到任何解决方案。
JSONField
[Django-doc]。在关系数据库中,JSONField
几乎总是会破坏第一范式 [wiki],而您想要搜索所有记录的情况实际上证明它破坏了第一范式:所有列都应被视为原子值是指您不想查看子结构。但在这里你显然这样做了。
特别是由于数据是结构化的,没有理由使用
JSONField
,请使用带有 ForeignKey
[Django-doc]: 的额外模型
class Practitioner(models.Model):
name = models.CharField(max_length=128, unique=True)
class Specialty(models.Model):
practicioner = models.ForeignKey(
Practitioner, on_delete=models.PROTECT, related_name='specialties'
)
issued_on = models.DateField()
type = models.CharField(max_length=128)
specialty = models.CharField(max_length=128)
然后我们查询:
Practitioner.objects.filter(specialties__specialty='Anesthesiology')
由于像
type
和 specialty
这样的值似乎是分类的,您甚至可能想为它们创建额外的模型,并将 ForeignKey
中的 Specialty
添加到这些额外模型中。这也会减少数据库的大小,使查询更加高效,但这也许是首先引入范式的主要原因:如果您需要更新 specialty
的名称,那很容易。