Cơ sở dữ liệu của ứng dụng của tôi được điền và giữ syncd với các nguồn dữ liệu ngoài. Tôi có một mô hình trừu tượng mà tất cả các mô hình ứng dụng Django 2.2 của tôi xuất phát, được định nghĩa như sau:
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")
Các object_id
lĩnh vực không thể được thiết lập như là duy nhất vì mỗi nguồn dữ liệu tôi sử dụng trong ứng dụng của tôi có thể có một đối tượng với một object_id = 1
. Do đó, cần phải theo dõi nguồn gốc của đối tượng, theo trường object_origin
.
Thật không may, ORM của Django không hỗ trợ các khóa ngoại nhiều hơn một cột.
Vấn đề
Trong khi giữ khóa chính được tạo tự động trong cơ sở dữ liệu ( id
), tôi muốn tạo khóa ngoại của mình và các mối quan hệ nhiều-nhiều xảy ra trên cả hai object_id
và object_origin
các trường thay vì khóa chính id
.
Những gì tôi đã thử
Tôi nghĩ về việc làm một cái gì đó như thế này:
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)
Nhưng Django phàn nàn về điều đó:
myapp.B.to_a_fk: (fields.E312) The to_field 'composed_object_origin_id' doesn't exist on the related model 'myapp.A'.
Và nghe có vẻ hợp pháp, Django ngoại trừ hồ sơ được đưa ra to_field
là một trường cơ sở dữ liệu. Nhưng không cần thêm trường mới vào CommonModel
vì tôi đã composed_object_type_id
xây dựng hai trường không thể rỗng ...