将通用关系保存到父类

时间:2015-08-27 00:40:20

标签: python django generics

我有一个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个对象中。我该怎么做?

1 个答案:

答案 0 :(得分:0)

好的,所以在完成了一半之后,我意识到这导致我与另一个应用程序的巨型boondoogle。以下是可能帮助其他人的中途解决方案。

我们使用djangos非常内部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
[]

正如我所说,大规模的boondoggle。因此,如果您完成此代码,我将很乐意接受编辑。