How do I create a bidirectional link between two doctypes?


I have a question regarding usage. I would like to create two Doctypes

Doctype 1
Doctype 2

In doctype 1 I have create a link field for Doctype 2. So now when I go to the Doctype1 form I can immediately create a Doctype2 entry and it’s immediately assigned to the Doctype1 Document.

I would like now to add a LInk field for Doctype1 entries to the Doctype2 form so it’s automatically field in inverse however it doesn’t get assigned automatically even though I created the Doctype2 entry from the Doctype1 form.


Seems like a bad design pattern to me. What is the use case?

You can achieve this with hooks. But note that in the event you want to any of these docs it won’t be possible, among other issues. Doc 1 linked to Doc 2 and Doc 2 linked to Doc 1: circular dependency

The use case is that I want to link a license holder (Doc1 about 40 fields and 2 tables) to a driver’s license (Doc2 about 30 fields) from the license holder doctype. This is needed in order to do quick data entries and looking up everything related to a license holder.

However I also need to create reports based on the license data so I have to use the report builder in the license doctype list, and also include some info from the license holder in that report. If I don’t do a one-to-one bidirectional relationship in this case I don’t see a way to retrieve data from the license holder doctype in these reports unless I start fetching pretty much all the fields from the driver license document in custom fields for the license holder doctype.

In OOP it’s not rare to have inverse relationships as well. In such cases and there are design patterns to handle Circular References. I don’t come from a Python background but I see it often in frameworks for PHP.

I also have to do this for 3 other license types which are also one-on-one relationship and then the number of fields increase substantially.

One way to do this would be to fetch the values on load, check how task table is loaded in projects for quick entry.

The task table relation looks like this.


But I don’t see how the values are loaded automatically in the TASK when it’s created. Could you tell me where to look for the function that loads it?

Also I noticed that if I do the following

  1. Create a project
  2. Create two tasks
  3. Save project.

The tasks get created and the project is automatically assigned to them.
Afterwards if I remove the tasks from the project and delete the project, The tasks still mention the name of the project in their description even though the project no longer exists. Seems like a bug.

That may be the case Project and task table Bug

Not necessarily.

For example, I could generate an invoice from a delivery note. This will create a link from the DN to the invoice. So far so good. However, from the invoice, I want to track back to the delivery note.

Currently this is not happening for me, and I have to go back to the order and try and match the quantities invoiced against the quantities delivered.

Hello friend, have you solve the query?

Hope you don’t mind reviving an old question.

While I agree circular references between objects in memory or SQL tables is a bad idea, in the design and UI it’s often very useful.
You have a contact and a company (customer company, not ERPNext company), you want to see all contacts related to a given company and also you want to see all companies related to the given contact

What you need is a Virtual Field, just query all documents that link back to the current document.
It would be really cool if Frappe offered it out of the box.