2016-11-29 11 views
4

In einem Kommentar zu this question answer fragte ich, wie ein Feld mit einer Default-Wert-Funktion entfernt werden. Zusammenfassend ist der Beispielcode:Wie entferne ich eine Default-Wert-Funktion in Django

def get_deadline(): 
    return datetime.today() + timedelta(days=20) 

class Bill(models.Model): 
    name = models.CharField(max_length=50) 
    customer = models.ForeignKey(User, related_name='bills') 
    date = models.DateField(default=datetime.today) 
    deadline = models.DateField(default=get_deadline) 

und meine Frage an den Code ist:

Wie entfernen Sie das deadline Feld wieder, während auch die get_deadline Funktion zu löschen? Ich habe ein Feld mit einer Funktion für einen Standardwert entfernt, aber jetzt stürzt Django beim Start nach dem Entfernen der Funktion ab. Ich könnte die Migration manuell bearbeiten, die in diesem Fall in ok wäre, aber was, wenn Sie einfach die Standardfunktion geändert, und wollte die alte Funktion entfernen?

Ich entfernte den Standardteil der Migration, die darauf bezogen, aber wie entfernen Sie es schön?

Der einzige Weg, den ich mir vorstellen kann, ist, die Migrationen zu zerquetschen, so dass die Migration mit der Funktion verschwindet, aber das ist nicht immer eine Option.

Antwort

4

Im Anschluss an die Dokumentation von Historical Models:

Verweise auf Funktionen in Feldoptionen wie upload_to und limit_choices_to und Model Manager Erklärungen mit Managern use_in_migrations = True mit in Migrationen serialisiert werden, so werden die Funktionen und Klassen müssen Solange eine Migration erfolgt, die auf sie verweist. Alle benutzerdefinierten Modellfelder müssen ebenfalls beibehalten werden, da diese direkt von Migrationen importiert werden.

.....

alten Referenzen zu entfernen, können Sie Squash Migrationen oder, wenn es nicht viele Referenzen sind, kopieren Sie sie in die Migration von Dateien.

eine Methode ist, den Wert von default Feldoption zu erhalten gleiche wie das, was für upload_to Feld beschrieben wird. Die Dokumentation bieten sich zwei Möglichkeiten für Sie, wenn Sie die Methode entfernen möchten:

  1. Squash-Migrationen - wenn Sie diese nicht mehr Datei
  2. bearbeiten Migration benötigen: Kopieren Funktionen Dateien Migration und die Referenz in bearbeiten Migration.

Updates von Kommentaren:

In Schritt 2 von bearbeiten Migrationsdatei, ich habe enthalten nur die Art und Weise in der Dokumentation beschrieben. Wie genau Sie die Migration bearbeiten, ist Ihre Entscheidung. Sie könnten die Funktion in die Migrationsdatei kopieren und die Referenz bearbeiten, oder Sie können einfach das Standardfeld aus der Migrationsdatei entfernen oder eine andere Funktion aus einer anderen Datei verwenden.

+0

Oder nach @ Alasdair Antwort: 3. Bearbeiten Sie die Migrationen zu verwenden andere (oder keine) Standard – beruic

+1

Ich würde sagen, dass beide Antworten nur zwei Schritte vorschlagen 1) die Migration quetschen 2) die Migration bearbeiten. Wie genau Sie die Migrationen bearbeiten, ist Ihre Entscheidung. Sie könnten die Funktion dort kopieren und die Referenz bearbeiten. Oder Sie können einfach das Standardfeld von dort entfernen, oder Sie können eine andere Funktion von woanders verwenden. :) – AKS

+0

Du solltest deine Antwort dann aktualisieren;) – beruic

0

Wie entfernen Sie das Deadline-Feld erneut, während Sie gleichzeitig die Funktion get_deadline löschen?

Ich denke, das Entfernen beide zur gleichen Zeit (das heißt „während“ die anderen tun) ist nicht der richtige Weg, es zu tun. Statt dessen:

  • eine Migration hinzufügen, um das Feld zu entfernen. Stellen Sie diese Migration als Revision N bereit.

  • Vergewissern Sie sich, dass die Funktion nicht mehr verwendet wird.

  • In Revision N + M (d. H. Eine spätere Revision) entfernen Sie die nicht verwendete Funktion.

Auf diese Weise wird die Datenbank den Zustand des Codes übereinstimmt, da die Migrationen Teil dieses Codezustand sind: Wenn Sie Ihre Datenbank wieder in den Zustand ab Revision N wandern, ist die Funktion da sein. Wenn Sie Ihre Datenbank in den Status ab Version N + M migrieren, benötigen Sie die Funktion nicht mehr.

+0

Das wird nicht funktionieren. Die Funktion wird in früheren Revisionen immer noch referenziert. – beruic

+0

Mit "Revisionen" meine ich "Migrationen" :) – beruic

2

Es sieht so aus, als ob Sie die Antwort für sich selbst herausgefunden haben. Bevor Sie die Funktion get_deadline entfernen, müssen Sie sie aus allen Migrationen entfernen, die sie verwenden. Dazu gibt es zwei Möglichkeiten:

  1. Bearbeiten der Migrationen, die get_deadline verwenden, um einen anderen Standard zu verwenden.
  2. quetschen Migrationen, um die Migrationen zu entfernen, die sich auf get_deadline beziehen.
+1

Oder nach @AKS Antwort: 3. Kopieren Sie Funktionen in Migrationsdateien und bearbeiten Sie die Referenz in der Migration – beruic

-2

Meine direkte Antwort löscht die sqlite3.db und löscht alle Migrationen mit Ausnahme der __init__.py im Migrationsordner in jeder App.

Dann wieder tun Python

$manage.py makemigrations 
$python manage.py migrate 
+0

Was passiert, wenn ich auf einem Live-System mit Daten bin, die ich mir nicht leisten kann, in einer MySQL- oder PostgreSQL-Datenbank zu verlieren? – beruic

+0

Dann ist das Kodieren von Live-Daten einfach eine schlechte Idee. Ich denke, –

+0

Nun, Migrationen wären überhaupt nicht notwendig, wenn es nicht möglich sein sollte, Live-Daten zu aktualisieren. Und wenn Sie Live-Daten nicht aktualisieren können, können Sie Ihre Software nicht weiterentwickeln. – beruic

Verwandte Themen