diff --git a/pghistory/core.py b/pghistory/core.py index fd085f9..31eea18 100644 --- a/pghistory/core.py +++ b/pghistory/core.py @@ -237,10 +237,14 @@ def _generate_history_field(tracked_model, field): """ field = tracked_model._meta.get_field(field) + # db_column is always a value even if the user didn't set it, so we + # need to double-check that it's different before we pass it through + db_column = field.db_column if field.db_column != field.name else None + if isinstance(field, models.BigAutoField): - return models.BigIntegerField() + return models.BigIntegerField(db_column=db_column) elif isinstance(field, models.AutoField): - return models.IntegerField() + return models.IntegerField(db_column=db_column) elif not field.concrete: # pragma: no cover # Django doesn't have any non-concrete fields that appear # in ._meta.fields, but packages like django-prices have diff --git a/pghistory/tests/migrations/0014_customautofieldmodel_custombigautofieldmodel_and_more.py b/pghistory/tests/migrations/0014_customautofieldmodel_custombigautofieldmodel_and_more.py new file mode 100644 index 0000000..9645539 --- /dev/null +++ b/pghistory/tests/migrations/0014_customautofieldmodel_custombigautofieldmodel_and_more.py @@ -0,0 +1,69 @@ +# Generated by Django 4.2.6 on 2024-09-24 17:46 + +import pgtrigger.compiler +import pgtrigger.migrations +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("tests", "0013_concreteparent_concretechild_concretechildevent_and_more"), + ] + + operations = [ + migrations.CreateModel( + name="CustomAutoFieldModel", + fields=[ + ( + "id", + models.AutoField(db_column="pk_id", primary_key=True, serialize=False), + ), + ], + ), + migrations.CreateModel( + name="CustomBigAutoFieldModel", + fields=[ + ( + "id", + models.BigAutoField(db_column="pk_id", primary_key=True, serialize=False), + ), + ], + ), + pgtrigger.migrations.RemoveTrigger( + model_name="ignoreautofieldssnapshotmodel", + name="update_update", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="ignoreautofieldssnapshotmodel", + name="delete_delete", + ), + pgtrigger.migrations.AddTrigger( + model_name="ignoreautofieldssnapshotmodel", + trigger=pgtrigger.compiler.Trigger( + name="update_update", + sql=pgtrigger.compiler.UpsertTriggerSql( + condition='WHEN (OLD."my_char_field" IS DISTINCT FROM (NEW."my_char_field") OR OLD."my_int_field" IS DISTINCT FROM (NEW."my_int_field"))', # noqa: E501 + func='INSERT INTO "tests_ignoreautofieldssnapshotmodelcreatedatupdatedatmychardc6b" ("created_at", "my_char_field", "my_int_field", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated_at") VALUES (OLD."created_at", OLD."my_char_field", OLD."my_int_field", _pgh_attach_context(), NOW(), \'update\', OLD."id", OLD."updated_at"); RETURN NULL;', # noqa: E501 + hash="e817c95f191e0d10b3e86643e2d8a050a864d45a", + operation="UPDATE", + pgid="pgtrigger_update_update_9dd1b", + table="tests_ignoreautofieldssnapshotmodel", + when="AFTER", + ), + ), + ), + pgtrigger.migrations.AddTrigger( + model_name="ignoreautofieldssnapshotmodel", + trigger=pgtrigger.compiler.Trigger( + name="delete_delete", + sql=pgtrigger.compiler.UpsertTriggerSql( + func='INSERT INTO "tests_ignoreautofieldssnapshotmodelcreatedatupdatedatmychardc6b" ("created_at", "my_char_field", "my_int_field", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated_at") VALUES (OLD."created_at", OLD."my_char_field", OLD."my_int_field", _pgh_attach_context(), NOW(), \'delete\', OLD."id", OLD."updated_at"); RETURN NULL;', # noqa: E501 + hash="c112d8f78e576e8fc9a895c72a92567c20b093a4", + operation="DELETE", + pgid="pgtrigger_delete_delete_42ea6", + table="tests_ignoreautofieldssnapshotmodel", + when="AFTER", + ), + ), + ), + ] diff --git a/pghistory/tests/models.py b/pghistory/tests/models.py index ccd173d..152dee2 100644 --- a/pghistory/tests/models.py +++ b/pghistory/tests/models.py @@ -18,6 +18,14 @@ class BigAutoFieldModel(models.Model): id = models.BigAutoField(primary_key=True) +class CustomAutoFieldModel(models.Model): + id = models.AutoField(primary_key=True, db_column="pk_id") + + +class CustomBigAutoFieldModel(models.Model): + id = models.BigAutoField(primary_key=True, db_column="pk_id") + + @pghistory.track(context_field=pghistory.ContextJSONField()) @pghistory.track( pghistory.InsertEvent("snapshot_no_id_insert"), diff --git a/pghistory/tests/test_core.py b/pghistory/tests/test_core.py index 3fd2094..cff0024 100644 --- a/pghistory/tests/test_core.py +++ b/pghistory/tests/test_core.py @@ -28,6 +28,12 @@ def test_generate_history_field(settings): field = pghistory.core._generate_history_field(test_models.BigAutoFieldModel, "id") assert isinstance(field, models.BigIntegerField) + # AutoField and BigAutoField should take a custom column name from the original + field = pghistory.core._generate_history_field(test_models.CustomAutoFieldModel, "id") + assert field.db_column == "pk_id" + field = pghistory.core._generate_history_field(test_models.CustomBigAutoFieldModel, "id") + assert field.db_column == "pk_id" + @pytest.mark.django_db def test_image_field_snapshot():