Search code examples
djangoforeign-keys

Django. Foreign key


I have 2 tables:

Side and AdditionalCost

now AdditionalCost has the following foreign key field:

side = models.ForeignKey(Side, on_delete=models.CASCADE, related_name='costs')

I want to have another foreign key field in AdditionalCosts:

number_of_additional_installations = models.ForeignKey(Side, on_delete=models.CASCADE, related_name="number_of_additional_installations")

The Side model has the following field:

number_of_additional_installations = models.IntegerField(null=True, blank=True,
                                                             db_column='number_of_additional_installations',
                                                             verbose_name='Количество доп монтажей')

But I get the following error:

ERRORS:
<class 'kinetics.apps.address_program.admin.AdditionalCostInline'>: (admin.E202) 'address_program.AdditionalCost' has more than one ForeignKey to 'address_program.Side'.
address_program.AdditionalCost.number_of_additional_installations: (fields.E302) Reverse accessor for 'AdditionalCost.number_of_additional_installations' clashes with field name 'Side.number_of_additional_installations'.
        HINT: Rename field 'Side.number_of_additional_installations', or add/change a related_name argument to the definition for field 'AdditionalCost.number_of_additional_installations'.
address_program.AdditionalCost.number_of_additional_installations: (fields.E303) Reverse query name for 'AdditionalCost.number_of_additional_installations' clashes with field name 'Side.number_of_additional_installations'.
        HINT: Rename field 'Side.number_of_additional_installations', or add/change a related_name argument to the definition for field 'AdditionalCost.number_of_additional_installations'.

I cannot figure out why this happened because I see that code has these lines:

buyer_org = models.ForeignKey("acl.Organization", on_delete=models.SET_NULL, null=True, blank=True,
                                  related_name='buyer_costs')
    client_org = models.ForeignKey("acl.Organization", on_delete=models.SET_NULL, null=True, blank=True,
                                   related_name='client_costs')

that are obviously two foreign fields that relate to columns of one model.

If you need full code of the models let me know, it is quite large but I can add it if you need. Thank you

p.s. If I rename the related_name of number_of_additional_installations, i still get the following error:

ERRORS:
<class 'kinetics.apps.address_program.admin.AdditionalCostInline'>: (admin.E202) 'address_program.AdditionalCost' has more than one ForeignKey to 'address_program.Side'.

Solution

  • This is because you already have number_of_additional_installations defined in Sides which clashes with the related name you set in AdditionalCosts. Either you rename the field in Sides or you change the related_name parameter so it wont confuse Django which field to resolve.

    This code:

    buyer_org = models.ForeignKey("acl.Organization", on_delete=models.SET_NULL, null=True, blank=True,
                                      related_name='buyer_costs')
    client_org = models.ForeignKey("acl.Organization", on_delete=models.SET_NULL, null=True, blank=True,
                                       related_name='client_costs')
    

    is not the same case. These fields do not cause conflict because they are referring to different relationships even if they are referring to the same model. model.buyer_org and model.client_org returns different relationships. model.buyer_org maps with organization.buyer_costs which is exclusive of model.client_org which, in turn, maps to organization.client_costs.

    What's happening with the way you specify Sides and AdditionalCosts though creates conflict.

    You can call side.number_of_additional_installations which returns an integer field but at the same time you are telling django that the additional_costs.number_of_additional_installations map to side.number_of_additional_installations.