Chicken and the egg. You really have to constrain one before the other. I usually start with the output side. So let's say I have a 20ns clock period feeding both FPGAs, and a 1ns board delay. On FPGA 1 I might do:
create_clock -period 20.0 -name virt_clk
set_output_delay -clock virt_clk 20.0 [get_ports fpga1_dout*]
This is an impossible constraint, as it says the external device uses up all 20ns of the period and so fpga1 needs to get its data out in 0ns to meet timing. So I compile and find these outputs fail timing by -7.3ns. I would then change my output delay to:
set_output_delay -clock virt_clk 12.0 [get_ports fpga1_dout*]
This means the external device uses 12ns and fpga1 must get its data out in 8ns or less to meet timing. (You could make the output delay as high as 12.7 and it should work, but there might be some variation compile to compile, so if I can I put a little margin on it. You can tighten it later if need be). I may recompile just to make sure it meets timing.
Now onto FPGA2. We know FPGA1 gets its data out in 8ns or less, and the board delay is 1ns, so I would do:
set_input_delay -clock virt_clk 9.0 [get_ports fpga2_din*]
I am constraint FPGA2 in terms of the constraint I put into FPGA1. If something doesn't meet timing, I tweak it. If FPGA2 has 5ns of slack and FPGA1 has only 0.1ns of slack, I may shift the requirements to even it out some, but I absolutely don't have to either.
The problem with Report DataSheet is it's not a requirement. You might look at it after a compile and see that the Tco of fpga1 is 7.3ns, and then use that to constrain fpga2, but on another coompile it might be higher and don't want to check it after every compile. By constraint fpga2 in terms of the constraint you put on fpga1(and conversely fpga1 is now constrained based on the constraint you have for fpga2), if anything fails timing you will see it in TimeQuest.