Changes between Version 2 and Version 4 of Ticket #31788


Ignore:
Timestamp:
Jul 14, 2020, 9:30:13 PM (4 years ago)
Author:
Simon Charette
Comment:

I agree that you'll loose data but Alter(Index|Unique)Together should always be sorted before RemoveField

https://github.com/django/django/blob/b502061027b90499f2e20210f944292cecd74d24/django/db/migrations/autodetector.py#L910 https://github.com/django/django/blob/b502061027b90499f2e20210f944292cecd74d24/django/db/migrations/autodetector.py#L424-L430

So something's broken here in a few different ways and I suspect it's due to the fact the same field name project_data_set is reused for the many-to-many field.

If you start from

class Authors(models.Model):
    project_data_set = models.ForeignKey(
        ProjectDataSet,
        on_delete=models.PROTECT
    )
    state = models.IntegerField()
    start_date = models.DateField()

    class Meta:
         unique_together = (('project_data_set', 'state', 'start_date'),)

And generate makemigrations for

class Authors(models.Model):
    project_data_set = models.ManyToManyField(ProjectDataSet)
    state = models.IntegerField()
    start_date = models.DateField()

You'll get two migrations with the following operations

# 0002
operations = [ 
    migrations.AddField(
        model_name='authors',
        name='project_data_set',
        field=models.ManyToManyField(to='ticket_31788.ProjectDataSet'),
    ),
    migrations.AlterUniqueTogether(
        name='authors',
        unique_together=set(),
    ),
    migrations.RemoveField(
        model_name='authors',
        name='project_data_set',
    ),
]

# 0003
operations = [ 
    migrations.AddField(
        model_name='authors',
        name='project_data_set',
        field=models.ManyToManyField(to='ticket_31788.ProjectDataSet'),
    ),
]

If you change the name of the field to something else like project_data_sets every work as expected

operations = [ 
    migrations.AddField(
        model_name='authors',
        name='project_data_sets',
        field=models.ManyToManyField(to='ticket_31788.ProjectDataSet'),
    ),
    migrations.AlterUniqueTogether(
         name='authors',
         unique_together=set(),
    ),
    migrations.RemoveField(
        model_name='authors',
        name='project_data_set',
    ),
]

It seems like there's some bad interactions between generate_removed_fields and generate_added_fields when a field with the same name is added.

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #31788

    • Property Cc Markus Holtermann Simon Charette added
    • Property Triage Stage UnreviewedAccepted
  • Ticket #31788 – Description

    v2 v4  
    11I have models like
    22
    3 {{{
     3{{{#!python
    44class Authors(models.Model):
    5 
    6     project_data_set = models.ManyToManyField(
     5    project_data_set = models.ForeignKey(
    76        ProjectDataSet,
    87        on_delete=models.PROTECT
Back to Top