I also don't know about any generic solution but I followed the "dropdown" approach mentioned above. This works quite well if there are not too many objects to choose from for the has_one relation.
An Example:
I have a (potentially big) product list with products of only a few categories. Every Category has an associated Icon with a short descriptive Text. I therefore need a has_one relation (Product->Icon) and a has_many relation (Icon->Product)
Product is a Page, Icon is a DataObject.
The Icon DataObject is standard, as in all tutorials.
In the Product Page I use a GridField RecordEditor for adding and deleting the Icon DataObjects:
$icoconfig = GridFieldConfig_RecordEditor::create();
$idl = DataList::create('ProductIcon'); // get _all_ ProductIcon DataObjects!
$iconfield = new GridField(
'All Icons Grid', // Field name
'Product Icons', // Field title
$idl,
$icoconfig
);
$fields->addFieldToTab('Root.All Icons', $iconfield);
For relating one specific Icon to the Product I then use a DropdownField:
$drop = new DropdownField('MyIconID', 'Select Icon', ProductIcon::get()->map('ID','Name'));
$drop->setEmptyString('No Icon'); // Used for "no icon" input
$fields->addFieldToTab('Root.Main', $drop);
BTW: The ->map() function shows the Icon Name in the Dropdown Field whereas it uses the "ID" as selected value!
The MyIconID Table row gets added automatically if you have the according $has_one relation set up in the Product Page
static $has_one = array(
'MyIcon' => 'ProductIcon'
);
I hope this is helpful ant it's clear what I meant. If it is not, please ask again and I will try to improve what I have written. Overall it is just an explanation/example of the dropdown idea from the first post and it is only feasible if there are not too many DataObjects to choose from. A generic approach via GridField would therefore be very nice but in the meantime this might help. I have set it up that way and it works for me.