简体   繁体   English

保存与父类的通用关系

[英]Saving a generic relation to a parent class

I have a django model that I which to subclass that has a generic relationship attached that I wish to subclass: 我有一个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)

For clarity, I have to use a generic relation as department can also have contact details. 为了清楚起见,我必须使用一般关系,因为部门也可以有联系方式。

class Department(models.Model):
    contact_details = generic.GenericRelation('ContactDetail')

When I create a person, I can make and get their contact details like so: 创建一个人时,可以像这样建立并获取他们的联系信息:

> alice = Person(name="Alice")
> ContactDetail(content_object=alice,value="555-1000")
> print alice.contact_details
[ ... list of things ... ]

However, when I make a teacher this happens: 但是,当我当老师时会发生以下情况:

> 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
[]

Nothing is returned! 什么也没退!

What I want is for a teachers contact details to be stored against the Person objects and not the Teacher objects. 我想要的是针对Person对象而不是Teacher对象存储教师联系方式 How can I do this? 我怎样才能做到这一点?

Ok so after getting half way done I realised this was leading me down a giant boondoogle with another app. 好的,所以在完成一半的过程后,我意识到这正导致我在使用另一个应用程序时遇到巨大的死角。 So below is a half way solution that might help someone else. 因此,下面是一种可能对他人有所帮助的中途解决方案。

We make use of djangos very internal get_parent_list to get the parent models and operate on those: 我们在内部使用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

Why is this a half solution? 为什么这是半解决方案? Well, this will appropriately save the GenericRelation against the parent class, so this will work: 好吧,这将适当地将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 ... ]

But, we've just messed things around so the problem is now backwards! 但是,我们只是把事情弄糟了,所以问题现在倒退了! Because if we try and get bob s details there are none! 因为如果我们尝试获取bob的详细信息,则没有任何信息!

> print bob.contact_details
[]

As I said, massive boondoggle. 如我所说,巨大的笨蛋。 So if you finish this code, I'll gladly accept an edit. 因此,如果您完成此代码,我将很乐意接受修改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM