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