Мои модели настраиваются следующим образом (это - пример и не мои фактические модели),
class modelA(Model):
field1 = CharField(max_length=50)
class modelB(modelA):
field2 = CharField(max_length=50)
class anotherModel(Model):
connection = models.ForeignKey(modelA)
title = CharField(max_length=50)
Я смог бы иметь соединение с modelB, сохраненным в anotherModel, так как modelB наследовался модели A.
mod_b = modelB()
conn_b = anotherModel()
conn_b.connection = mod_b
Если не, как я обработал бы это?
Спасибо
Функция Generic Relations из встроенного в Django модуля ContentTypes является наиболее поддерживаемым способом обработки полиморфных внешних ключей.
Вам нужно будет добавить некоторые вспомогательные поля в вашу модель, чтобы фреймворк мог определить, какой конкретный класс представляет внешний ключ, но в остальном он будет загружать нужный тип достаточно прозрачно.
В вашем случае это будет что-то вроде:
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
# modelA and modelB as before
class anotherModel(Model):
connection_content_type = models.ForeignKey(ContentType)
connection_object_id = models.PositiveIntegerField()
connection = generic.GenericForeignKey('connection_content_type',
'connection_object_id')
Обратите внимание, что вам не нужно устанавливать/читать поля connection_content_type
или connection_object_id
самостоятельно... фреймворк дженериков сделает это за вас, они просто должны быть там, чтобы дженерики работали.
mod_a = modelA()
mod_b = modelB()
conn = anotherModel()
conn.connection = mod_b
conn.save()
conn.connection = mod_a # change your mind
conn.save()
Да, вы можете это сделать. Если вы добавите ForeignKey в «anotherModel» в modelB и попытаетесь запустить syncdb, он будет лаять на вас, говоря, что вам нужно указать «related_name». Итак, в одном (или обоих) ваших полях ForeignKey добавьте атрибут related_name.
Вы также должны прочитать это: http://docs.djangoproject.com/en/dev/topics/db/models/#be-careful-with-related-name , чтобы получить больше информация о related_name.