2014-09-08 16 views
5

Ich benutze Django 1.7 und ich habe ein Problem mit meinen Fixtures.Django Fixtures speichern mit Standardwert

Ich möchte, dass Django den Standardwert verwendet oder die Methode save() verwendet, um nicht spezifizierte Werte zu erstellen.

Hier sind meine aktuellen Objekte:

# File: uuidable.py 
import uuid 
from django.db import models 
from django.utils.translation import ugettext_lazy as _ 


class Uuidable(models.Model): 
    uuid = models.CharField(_('uuid'), blank=True, 
          null=False, unique=True, 
          max_length=64, default=uuid.uuid4()) # Tried here 

    class Meta: 
     abstract = True 

    def save(self, *args, **kwargs): 
     if self.pk is None: 
      self.uuid = uuid.uuid4() # Tried here also 
     super().save(*args, **kwargs) 

# File: timestampable.py 
from django.db import models 
from django.utils.translation import ugettext_lazy as _ 


class Timestampable(models.Model): 
    created_at = models.DateTimeField(_('created at'), auto_now_add=True) 
    updated_at = models.DateTimeField(_('updated at'), auto_now=True) 

    class Meta: 
     abstract = True 

# File: post.py 
from project.lib.models.timestampable import Timestampable 
from project.lib.models.uuidable import Uuidable 

class Post(Timestampable, Uuidable): 
    title = models.CharField(_('title'), max_length=250, blank=False) 
    content = models.TextField(_('content')) 

    def __str__(self): 
     return self.title 

Wie man sehen kann, wenn ich eine neue Post() erzeugen, die created_at, updated_at und uuid Werte werden auf save() automatisch erstellt. Aber wenn ich Armaturen verwenden, ich die folgende Fehlermeldung erhalten:

[...]initial_data.yaml': Could not load post.Post(pk=None): UNIQUE constraint failed: post_post.uuid 

Wenn ich ein uuid in meiner Befestigungsdatei angeben, dann bekomme ich einen Fehler auf created_at und dann auf updated_at. Also muss ich den Inhalt jedes Feldes angeben, obwohl ich möchte, dass es "automatisch" ist.

Vom documentation (warum ist das in der django Admin docs?!), Ich weiß, dass die save() Methode nicht so genannt wird, das ist, warum alles, was ich in die save() Methode setzen funktioniert nicht. Aber sollten nicht die default oder auto_now* Funktionen aktiviert/verwendet werden?

When fixture files are processed, the data is saved to the database as is. Model defined save() methods are not called, and any pre_save or post_save signals will be called with raw=True since the instance only contains attributes that are local to the model. You may, for example, want to disable handlers that access related fields that aren’t present during fixture loading and would otherwise raise an exception

Gibt es eine Möglichkeit zu „zwingen“ Django automatisch die default oder auto_now* Funktionen für die Lampen zu benutzen? Ich benutze manage.py syncdb, um alle Tabellen usw. zu erstellen.

Ich habe auf Google und Stack-Überlauf gesucht, konnte aber nicht die richtigen Suchbegriffe finden.

UPDATE-1: Die folgenden google group discussion sagt, dass Objekte in raw Modus gespeichert werden, was bedeutet, dass auto_now* Funktionen werden nicht berücksichtigt. Ich bin immer noch auf der Suche nach einer Möglichkeit, eine Modellfunktion an die Django-Scheinwerferspeicherung anzuhängen.

import uuid 
from django.db import models 
from django.utils.translation import ugettext_lazy as _ 
from django.db.models.signals import pre_save 
from django.dispatch import receiver 

class Uuidable(models.Model): 
    uuid = models.CharField(_('uuid'), blank=True, 
          null=False, unique=True, 
          max_length=64, default=uuid.uuid4()) 

    class Meta: 
     abstract = True 

    @receiver(pre_save) 
    def set_uuid_on_save(sender, instance, *args, **kwargs): 
     if instance.pk is None: 
      instance.uuid = uuid.uuid4() 

Auf diese Weise wird das Modell/Daten besiedelten welcher Weise auch immer Sie das Modell erstellen (via Shell, Spiele, was auch immer):

+0

Können Sie eine Datenmigration verwenden statt einer Befestigung? Das hat auch den Vorteil, dass sie weiter funktionieren, wenn Sie das Modell später mit einer Schemamigration ändern. – RemcoGerlich

+0

Ich habe im Moment ein bisschen zu viele Daten, um einfach zu Migrationen zu wechseln. Aber ich weiß, dass es ein besserer Ansatz ist. – achedeuzot

+0

Eine gute Seite Frage über Migrationen während der anfänglichen Entwicklung http://StackOverflow.com/Questions/5021800/Why-use-South-During-Initial-Entwicklung – achedeuzot

Antwort

5

Die Lösung django Signale zu verwenden war.

1

Automatically loading initial data fixtures is deprecated in Django 1.7. Eine Lösung ist über Signale, wie Sie erwähnt haben. Ein weiteres ein, dass ich es vorziehen, ist ein Python-Skript zu erstellen, wo Sie alle benötigten Daten zu erstellen, und es in der Shell ausführen:

python manage.py shell < create_initial_data.py 
+2

Ich liebe die Idee des Python-Skripts, die Sie vorschlagen! Aber im Moment habe ich ein bisschen zu viele Daten, um es einfach in dieses Format zu konvertieren. – achedeuzot

+0

Das ist falsch: ** Automatisches Laden ** von Geräten wurde in 1.7 veraltet. – Rainy

+1

Sie haben Recht. Ich bearbeite jetzt die Antwort. Vielen Dank! – ferrangb

Verwandte Themen