Tutorial :django model with two generic (content_type) foreign keys?



Question:

I'm trying to create a mapping table between two generic (content_type) references, one for "agents" and one for "resources".

So I take the usual way I make a generic foreign key :

content_type = models.ForeignKey(ContentType)  object_id = models.PositiveIntegerField()  resource = generic.GenericForeignKey('content_type', 'object_id')  

And I try to make a model with two.

agent_content_type = models.ForeignKey(ContentType)  agent_object_id = models.PositiveIntegerField()  agent = generic.GenericForeignKey('agent_content_type', 'agent_object_id')    resource_content_type = models.ForeignKey(ContentType)  resource_object_id = models.PositiveIntegerField()  resource = generic.GenericForeignKey('resource_content_type', 'resource_object_id')  

But this now throws up the following errors :

myapp.mymodel: Accessor for field 'resource_content_type' clashes with related field 'ContentType.mymodel_set'. Add a related_name argument to the definition for 'resource_content_type'.

And similar for the agent.

What's going on here? And what should I do?

cheers

phil


Solution:1

Have you tried doing what the error message tells you to do - add a related_name argument?

agent_content_type = models.ForeignKey(ContentType, related_name='mymodel_agent')  

Edit: The reason why it happens is that every time you define a foreign key, Django automatically gives the target model an attribute to do the reverse lookup. By default, it gives this the name of the related table + '_set' - so if your article table has an FK to section, section will get an article_set attribute for the reverse lookup.

Now if you have two FKs in the same model pointing at the same target model, Django will try and give them both the foo_set attribute, leading to a collision. Hence the error message, which tells you to set the related_name attribute manually.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »