我有一个django模型,我有一个子类,有一个泛型关系附加,我希望子类:
class Person(models.Model):
name = models.CharField(max_length=255)
contact_details = generic.GenericRelation('ContactDetail')
class Teacher(Person):
field_of_study = models.CharField(max_length=255,default="Underwater Basket-weaving")
class ContactDetail(models.Model):
content_type = models.ForeignKey(ContentType, blank=True, null=True)
object_id = models.CharField(blank=True, null=True, max_length=256)
content_object = generic.GenericForeignKey('content_type', 'object_id')
value = models.CharField(max_length=256)
为了清楚起见,我必须使用通用关系,因为部门也可以有联系方式。
class Department(models.Model):
contact_details = generic.GenericRelation('ContactDetail')
当我创建一个人时,我可以创建和获取他们的联系方式,如下所示:
> alice = Person(name="Alice")
> ContactDetail(content_object=alice,value="555-1000")
> print alice.contact_details
[ ... list of things ... ]
然而,当我成为一名老师时,这种情况发生了:
> bob = Teacher(name="Bob")
> ContactDetail(content_object=bob,value="555-2000")
> print bob.contact_details
[ ... list of things ... ]
> bob_person = Person.get(name="Bob") # Returns the person instance of Bob
> print bob_person.contact_details
[]
不返回任何内容!
我想要的是针对Person
对象和而不是Teacher
对象存储教师联系方式详细信息。我该怎么做呢?
在完成了一半之后,我意识到这让我在另一个应用程序上陷入了巨大的困境。所以下面是一个可能会帮助其他人的一半解决方案。
我们使用django非常内部的get_parent_list
来获取父模型并对其进行操作:
@receiver(pre_save, sender=ContactDetail)
def set_object_to_super(sender, **kwargs):
obj = kwargs['instance']
c_obj = obj.content_object
parents = c_obj._meta.get_parent_list() # Beware: This is a set, not a list!
if len(parents) == 0:
# If no parents, its a base class
return
elif len(parents) == 1:
# If only one parent, get that from the object
parent = list(parents)[0]
obj.content_object = getattr(c_obj, '%s_ptr'%parent._meta.model_name)
else:
# Here's where it gets tricky, there are two or more base classes
# You, dear reader, will need to figure out which to use!
# Remember, you can only have one.
pass
为什么这是一个半解决方案?那么,这将适当地保存GenericRelation
对父类,所以这将工作:
> bob = Teacher(name="Bob")
> ContactDetail(content_object=bob,value="555-2000")
> bob_person = Person.get(name="Bob") # Returns the person instance of Bob
> print bob_person.contact_details
[ ... list of things ... ]
但是,我们只是把事情搞砸了,所以问题现在是反过来的!因为如果我们试图获得bob
的详细信息,没有!
> print bob.contact_details
[]
就像我说的,大量的无用之物。因此,如果您完成了这段代码,我很乐意接受编辑。