raw_id_admin uses oldforms.!IntegerField if one relation in multiple relations does not use raw_id_admin=True
|Reported by:||shanx||Owned by:||nobody|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
First of all a disclaimer: this is quite a specific case that will be fixed by the upcoming newforms-admin branch. Still I report it here as a solution for people running in to this.
Note: the example uses a OneToOneField relation, but this also works with ForeignKey relations.
The use case for us is as follows: we have airlines which is a dataset provided by a third party (galileo):
class GalileoAirline(models.Model): id = models.CharField(_('code'), primary_key=True, max_length=3)
On top of that we have a concept of an !Airline in our own internal system:
class FlightAirline(models.Model): galileo_airline = models.OneToOneField(GalileoAirline, primary_key=True)
Now in the rest of our application we only make use of our own concepts, for example for defining specific margins per airline:
class AirlineMargin(models.Model): airline = models.OneToOneField(FlightAirline, primary_key=True, raw_id_admin=True)
This setup fails in the admin when one tries to add and save an AirlineMargin. This is because !Django returns the airline field in AirlineMargin as an oldforms.IntegerField. Though this bug was reported and fixed back in the day by #586. That fix works for one relation, in this case we traverse two relations, since FlightAirline does not have a raw_id_admin=True. The admin reverts to using IntegerField.
The fix for this is to use raw_id_admin=True for _all_ in between relations. In this case changing FlightAirline to:
class FlightAirline(models.Model): galileo_airline = models.OneToOneField(GalileoAirline, primary_key=True, raw_id_admin=True)