アプリのデータベースにデータが入力され、外部データソースとの同期が維持されます。私のDjango 2.2アプリのすべてのモデルが派生する抽象モデルがあり、次のように定義されています。
class CommonModel(models.Model):
# Auto-generated by Django, but included in this example for clarity.
# id = models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')
ORIGIN_SOURCEA = '1'
ORIGIN_SOURCEB = '2'
ORIGIN_CHOICES = [
(ORIGIN_SOURCEA, 'Source A'),
(ORIGIN_SOURCEB, 'Source B'),
]
object_origin = models.IntegerField(choices=ORIGIN_CHOICES)
object_id = models.IntegerField()
class A(CommonModel):
some_stuff = models.CharField()
class B(CommonModel):
other_stuff = models.IntegerField()
to_a_fk = models.ForeignKey("myapp.A", on_delete=models.CASCADE)
class C(CommonModel):
more_stuff = models.CharField()
b_m2m = models.ManyToManyField("myapp.B")
object_id
フィールドがユニークとして設定することはできません私は私のアプリで使用した各データソースが持つオブジェクトを持っているかもしれないのでobject_id = 1
。したがって、フィールドによってオブジェクトの原点を追跡する必要がありますobject_origin
。
残念ながら、DjangoのORMは複数の列の外部キーをサポートしていません。
問題
自動生成された主キーをデータベース(id
)に保持しながら、外部キーと多対多の関係を主キーではなくフィールドobject_id
とobject_origin
フィールドの両方で発生させたいと思いますid
。
私が試したこと
私はこのようなことをすることを考えました:
class CommonModel(models.Model):
# Auto-generated by Django, but included in this example for clarity.
# id = models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')
ORIGIN_SOURCEA = '1'
ORIGIN_SOURCEB = '2'
ORIGIN_CHOICES = [
(ORIGIN_SOURCEA, 'Source A'),
(ORIGIN_SOURCEB, 'Source B'),
]
object_origin = models.IntegerField(choices=ORIGIN_CHOICES)
object_id = models.IntegerField()
def _get_composed_object_origin_id(self):
return f"{self.object_origin}:{self.object_id}"
composed_object_origin_id = property(_get_composed_object_origin_id)
class A(CommonModel):
some_stuff = models.CharField()
class B(CommonModel):
other_stuff = models.IntegerField()
to_a_fk = models.ForeignKey("myapp.A", to_field="composed_object_origin_id", on_delete=models.CASCADE)
しかしDjangoはそれについて不平を言っています:
myapp.B.to_a_fk: (fields.E312) The to_field 'composed_object_origin_id' doesn't exist on the related model 'myapp.A'.
そして、それは合法的に聞こえますが、Django to_field
はデータベースフィールドとして指定されたフィールドを除きました。しかし、は2つのnull可能ではないフィールドを使用して構築されているCommonModel
ので、新しいフィールドを追加する必要はありませんcomposed_object_type_id
...