| 1461 | @skipUnlessDBFeature('supports_foreign_keys') |
| 1462 | def test_alter_field_pk_m2m(self): |
| 1463 | """ |
| 1464 | Tests the AlterField operation on primary keys changes any FKs pointing to it. |
| 1465 | """ |
| 1466 | project_state = self.set_up_test_model("test_alflpkm2m", second_model=True) |
| 1467 | |
| 1468 | project_state = self.apply_operations("test_alflpkm2m", project_state, operations=[ |
| 1469 | migrations.AddField( |
| 1470 | "Pony", "stables", |
| 1471 | models.ManyToManyField("Stable", related_name="ponies") |
| 1472 | ) |
| 1473 | ]) |
| 1474 | |
| 1475 | # Test the state alteration |
| 1476 | operation = migrations.AlterField("Pony", "id", models.FloatField(primary_key=True)) |
| 1477 | new_state = project_state.clone() |
| 1478 | operation.state_forwards("test_alflpkm2m", new_state) |
| 1479 | self.assertIsInstance(project_state.models["test_alflpkm2m", "pony"].get_field_by_name("id"), models.AutoField) |
| 1480 | self.assertIsInstance(new_state.models["test_alflpkm2m", "pony"].get_field_by_name("id"), models.FloatField) |
| 1481 | |
| 1482 | def assertIdTypeEqualsFkType(): |
| 1483 | with connection.cursor() as cursor: |
| 1484 | id_type, id_null = [ |
| 1485 | (c.type_code, c.null_ok) |
| 1486 | for c in connection.introspection.get_table_description(cursor, "test_alflpkm2m_pony") |
| 1487 | if c.name == "id" |
| 1488 | ][0] |
| 1489 | fk_type, fk_null = [ |
| 1490 | (c.type_code, c.null_ok) |
| 1491 | for c in connection.introspection.get_table_description(cursor, "test_alflpkm2m_pony_stables") |
| 1492 | if c.name == "pony_id" |
| 1493 | ][0] |
| 1494 | self.assertEqual(id_type, fk_type) |
| 1495 | self.assertEqual(id_null, fk_null) |
| 1496 | |
| 1497 | assertIdTypeEqualsFkType() |
| 1498 | # Test the database alteration |
| 1499 | with connection.schema_editor() as editor: |
| 1500 | operation.database_forwards("test_alflpkm2m", editor, project_state, new_state) |
| 1501 | assertIdTypeEqualsFkType() |
| 1502 | # And test reversal |
| 1503 | with connection.schema_editor() as editor: |
| 1504 | operation.database_backwards("test_alflpkm2m", editor, new_state, project_state) |
| 1505 | assertIdTypeEqualsFkType() |
| 1506 | |
| 1507 | @skipUnlessDBFeature('supports_foreign_keys') |
| 1508 | def test_alter_field_pk_m2m_through(self): |
| 1509 | """ |
| 1510 | Tests the AlterField operation on primary keys changes any FKs pointing to it. |
| 1511 | """ |
| 1512 | project_state = self.set_up_test_model("test_alflpkm2mthrough", second_model=True) |
| 1513 | |
| 1514 | project_state = self.apply_operations("test_alflpkm2mthrough", project_state, operations=[ |
| 1515 | migrations.CreateModel("PonyStables", fields=[ |
| 1516 | ("pony", models.ForeignKey('test_alflpkm2mthrough.Pony', models.CASCADE)), |
| 1517 | ("stable", models.ForeignKey('test_alflpkm2mthrough.Stable', models.CASCADE)), |
| 1518 | ]), |
| 1519 | migrations.AddField( |
| 1520 | "Pony", "stables", |
| 1521 | models.ManyToManyField("Stable", related_name="ponies", through='test_alflpkm2mthrough.PonyStables') |
| 1522 | ) |
| 1523 | ]) |
| 1524 | self.assertTableExists("test_alflpkm2mthrough_ponystables") |
| 1525 | |
| 1526 | # Test the state alteration |
| 1527 | operation = migrations.AlterField("Pony", "id", models.FloatField(primary_key=True)) |
| 1528 | new_state = project_state.clone() |
| 1529 | operation.state_forwards("test_alflpkm2mthrough", new_state) |
| 1530 | self.assertIsInstance(project_state.models["test_alflpkm2mthrough", "pony"].get_field_by_name("id"), models.AutoField) |
| 1531 | self.assertIsInstance(new_state.models["test_alflpkm2mthrough", "pony"].get_field_by_name("id"), models.FloatField) |
| 1532 | |
| 1533 | def assertIdTypeEqualsFkType(): |
| 1534 | with connection.cursor() as cursor: |
| 1535 | id_type, id_null = [ |
| 1536 | (c.type_code, c.null_ok) |
| 1537 | for c in connection.introspection.get_table_description(cursor, "test_alflpkm2mthrough_pony") |
| 1538 | if c.name == "id" |
| 1539 | ][0] |
| 1540 | fk_type, fk_null = [ |
| 1541 | (c.type_code, c.null_ok) |
| 1542 | for c in connection.introspection.get_table_description(cursor, "test_alflpkm2mthrough_ponystables") |
| 1543 | if c.name == "pony_id" |
| 1544 | ][0] |
| 1545 | self.assertEqual(id_type, fk_type) |
| 1546 | self.assertEqual(id_null, fk_null) |
| 1547 | |
| 1548 | assertIdTypeEqualsFkType() |
| 1549 | # Test the database alteration |
| 1550 | with connection.schema_editor() as editor: |
| 1551 | operation.database_forwards("test_alflpkm2mthrough", editor, project_state, new_state) |
| 1552 | assertIdTypeEqualsFkType() |
| 1553 | # And test reversal |
| 1554 | with connection.schema_editor() as editor: |
| 1555 | operation.database_backwards("test_alflpkm2mthrough", editor, new_state, project_state) |
| 1556 | assertIdTypeEqualsFkType() |
| 1557 | |
| 1558 | |