我在尝试通过 Django Application 获取一些 manytomany 相关数据时遇到了一些问题
这是我的模型:
SoftwareVersion(models.Model):
id = models.AutoField(
primary_key=True,
db_index=True
)
... Some other fields ...
incompatibilities= models.ManyToManyField(
"self",
symmetrical=True,
blank=True,
default=None,
through="Incompatibilities"
)
Incompatibilities(models.Model):
id = models.AutoField(
primary_key=True,
db_index=True
)
softwareversion_a = models.ForeignKey(
"SoftwareVersion",
models.CASCADE,
db_index=True,
db_column='softwareversion_a ',
related_name='softwareversion_a',
verbose_name="software version a",
)
softwareversion_b = models.ForeignKey(
"SoftwareVersion",
models.CASCADE,
db_index=True,
db_column='softwareversion_b',
related_name='softwareversion_b',
verbose_name="softwareversion_b",
)
status = models.BooleanField(
verbose_name='Status',
default=False
)
class Meta:
unique_together = (('softwareversion_a', 'softwareversion_b'),)
为此,我在 SoftwareVersion 的保存方法中添加了一个逻辑,用于为每个新软件版本创建相关的不兼容性。我已经尝试了几种方法来做到这一点(使用循环或使用 bulk_create)这是我使用的批量创建功能:
# Inside SoftwareVersion Model class
def save(self, force_insert=False, force_update=False, using=None, update_fields=None) -> None:
save = super().save(force_insert, force_update, using, update_fields)
Incompatibilities.objects.bulk_create(
(Incompatibilities(
softwareversion_a=self,
softwareversion_b=software_version,
status=False
) for software_version in SoftwareVersion.objects.exclude(self)),
ignore_conflicts=True,
batch_size=1000
)
return save
我遇到的第一个问题是此方法忽略了 unique_together 约束,它会创建重复项。 在我使用每个 SoftwareVersion 上的循环来创建一个对象之前,它太长了,所以我想使用 bulk_create,但它似乎无法按我的预期工作。是否有另一种优化方法来执行此操作或要传递的参数,以便遵守唯一的共同约束。
其次,查询“给出该软件版本的所有不兼容”的最优化方式是什么。目前我正在这样做:
Incompatibilities.objects.filter(softwareversion_a=?)
但我实际上错过了在“softwareversion_b”字段中引用软件版本的不兼容性。 我尝试使用逻辑:
VersionLogiciel.objects.get(pk=?).incompatibilities.all()
但是 django 输出相同的 SQL 请求,所以,相同的结果。
Incompatibilities.objects.filter(softwareversion_a=?)
是否有一个参数可以放在某个地方,以便两个字段(这里是'softwareversion_a','softwareversion_b')可以互换。或者我可能必须以特定方式查询才能访问不兼容对象。我试过查询:
Incompatibilities.objects.filter(Q(softwareversion_a=?) or Q(softwareversion_b=?))
但是因为我必须在 softwareversion_a 相关字段和 softwareversion_b 相关字段上订购结果,所以我无法让它按我想要的方式工作。
PS:抱歉我的英语不好,请注意我将模型翻译成英文,所以我可能犯了一些错误,但在我这边,模型编译和迁移正在按预期工作。
在此先感谢您的帮助。