0

I am having a problem using inspectdb in django for a legacy database. I believe my issue is essentially the opposite of what is described here:

Django suffix ForeignKey field with _id

Many field names in my database end with "_id". Upon running inspectdb, those fields which end in "_id" and are also ForeignKeys or OneToOneFields have the "_id" removed:

class AssayClassMap(models.Model):
    ass_cls_map_id = models.BigIntegerField(primary_key=True)
    assay = models.ForeignKey('Assays', models.DO_NOTHING, blank=True, null=True)

I can fix this by changing the above lines to this:

class AssayClassMap(models.Model):
    ass_cls_map_id = models.BigIntegerField(primary_key=True)
    assay_id = models.ForeignKey('Assays', models.DO_NOTHING, blank=True, null=True, db_column='assay_id')

The issue is that there are hundreds of these that will need to be manually changed each time the model file is generated both for this database and other databases. I can come up with a script to correct these problems but I'd like to think there is some workaround.

Thanks

Dylan
  • 13
  • 3
  • 1
    Why is this an issue? The field name in the database will still include _id, since Django appends "_id" to all foreign keys. And when you're setting a value to these fields, you either set the object (assay=AssayObject).or value to a field name with appended "_id" (assay_id=1). – Borut Feb 21 '20 at 21:25
  • I believe I'm now seeing that the issue may be in the "model_to_dict" function. The output dictionary keys correspond to the Django model field name (missing "_id") and not to the database field name – Dylan Feb 21 '20 at 22:01
  • I was able to solve it! The issue was in the model_to_dict function rather than a django problem – Dylan Feb 21 '20 at 22:33

1 Answers1

0

I solved the problem. It was an issue with the model_to_dict function rather than a django function. I had to rewrite the model_to_dict function for my needs as follows:

def custom_to_dict(instance, fields=None, exclude=None):
    opts = instance._meta
    data = {}
    for f in chain(opts.concrete_fields, opts.private_fields, opts.many_to_many):
        if not getattr(f, 'editable', False):
            continue
        if fields and f.attname not in fields:
            continue
        if exclude and f.attname in exclude:
            continue
        data[f.attname] = f.value_from_object(instance)
    return data

Any instance of f.name was changed to f.attname. This preserves the "_id" suffix

Dylan
  • 13
  • 3