Commit 63fc91b3 authored by Moayad Mardini's avatar Moayad Mardini Committed by Tim Graham
Browse files

Fixed #22676 -- makemigrations --dry-run should not ask for defaults

Made the fix in InteractiveMigrationQuestioner class code, rather than
MigrationAutodetector, because --dry-run shouldn't affect whether
MigrationAutodetector will detect non-nullable fields, but the
questioner should skip the question and returns a None for default
(since that won't be used anyway) if --dry-run is used.
parent 9fb0f5dd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ class Command(BaseCommand):
        autodetector = MigrationAutodetector(
            loader.project_state(),
            ProjectState.from_apps(apps),
            InteractiveMigrationQuestioner(specified_apps=app_labels),
            InteractiveMigrationQuestioner(specified_apps=app_labels, dry_run=self.dry_run),
        )

        # If they want to make an empty migration, make one for each app
+35 −32
Original line number Diff line number Diff line
@@ -18,9 +18,10 @@ class MigrationQuestioner(object):
    interactive subclass is what the command-line arguments will use.
    """

    def __init__(self, defaults=None, specified_apps=None):
    def __init__(self, defaults=None, specified_apps=None, dry_run=None):
        self.defaults = defaults or {}
        self.specified_apps = specified_apps or set()
        self.dry_run = dry_run

    def ask_initial(self, app_label):
        "Should we create an initial migration for the app?"
@@ -93,6 +94,7 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):

    def ask_not_null_addition(self, field_name, model_name):
        "Adding a NOT NULL field to a model"
        if not self.dry_run:
            choice = self._choice_input(
                "You are trying to add a non-nullable field '%s' to %s without a default;\n" % (field_name, model_name) +
                "we can't do that (the database needs something to populate existing rows).\n" +
@@ -124,6 +126,7 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):
                            return eval(code, {}, {"datetime": datetime_safe})
                        except (SyntaxError, NameError) as e:
                            print("Invalid input: %s" % e)
        return None

    def ask_rename(self, model_name, old_name, new_name, field_instance):
        "Was this field really renamed?"
+20 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ import os
import shutil

from django.apps import apps
from django.db import models
from django.core.management import call_command, CommandError
from django.db.migrations import questioner
from django.test import override_settings, override_system_checks
@@ -362,3 +363,22 @@ class MakeMigrationsTests(MigrationTestBase):
        self.assertIn("Merging migrations", stdout.getvalue())
        self.assertIn("Branch 0002_second", stdout.getvalue())
        self.assertIn("Branch 0002_conflicting_second", stdout.getvalue())

    @override_system_checks([])
    @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_default"})
    def test_makemigrations_dry_run(self):
        """
        Ticket #22676 -- `makemigrations --dry-run` should not ask for defaults.
        """

        class SillyModel(models.Model):
            silly_field = models.BooleanField(default=False)
            silly_date = models.DateField()  # Added field without a default

            class Meta:
                app_label = "migrations"

        stdout = six.StringIO()
        call_command("makemigrations", "migrations", dry_run=True, stdout=stdout)
        # Output the expected changes directly, without asking for defaults
        self.assertIn("Add field silly_date to sillymodel", stdout.getvalue())
+23 −0
Original line number Diff line number Diff line
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations


class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='SillyModel',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('silly_field', models.BooleanField(default=False)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
    ]
+0 −0

Empty file added.