2014-09-08 12 views
5

Używam Django 1.7 i mam problem z moimi urządzeniami.Urządzenia Django zapisują z domyślną wartością

Chciałbym, aby Django używał wartości domyślnej lub używał metody save() do tworzenia nieokreślonych wartości.

Oto moje obecne obiekty:

# 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 

Jak widać, kiedy wygenerować nowy Post() wartości created_at, updated_at i uuid są tworzone automatycznie na save(). Ale kiedy używać urządzeń, pojawia się następujący błąd:

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

Gdybym określić uuid w moim pliku osprzętu, a następnie pojawia się błąd na created_at a następnie w updated_at. Muszę więc określić zawartość każdego pola, nawet jeśli chcę, aby była "automatyczna".

Z documentation (dlaczego jest to w Django administratora docs?!), Wiem, że metoda save() nie nazywa się tak dlatego wszystko, co umieścić w metodzie save() nie działa. Ale czy funkcje default lub auto_now* nie powinny być włączone/używane?

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

Czy istnieje sposób, aby „zmusić” Django automatycznie użyć default lub auto_now* możliwości dla lamp? Używam manage.py syncdb do tworzenia wszystkich tabel itp.

Szukałem w serwisie Google i stosu przepełnienia, ale nie mogłem znaleźć odpowiednich słów kluczowych w wyszukiwaniu.

UPDATE-1: Poniższy google group discussion mówi, że obiekty są zapisywane w trybie raw, co oznacza, że ​​auto_now* funkcje nie są brane pod uwagę. Nadal szukam, czy istnieje sposób na przechwycenie jakiejś funkcji modelu do zapisywania urządzenia Django.

+0

można użyć migracji danych zamiast urządzenia? Ma to także tę zaletę, że działają dalej, jeśli później zmienisz model z migracją schematu. – RemcoGerlich

+0

Mam obecnie zbyt dużo danych, aby łatwo przejść na migrację. Ale wiem, że to lepsze podejście. – achedeuzot

+0

Dobre poboczne pytanie dotyczące migracji podczas wstępnego rozwoju http://stackoverflow.com/questions/5021800/why-use-south-during-initial- development – achedeuzot

Odpowiedz

5

Rozwiązaniem było używać sygnałów django:

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() 

ten sposób model/danych jest zaludniony jakikolwiek sposób tworzenia modelu (przez skorupy, terminarz, cokolwiek).

1

Automatically loading initial data fixtures is deprecated in Django 1.7. Jednym z rozwiązań są sygnały, o których wspomniałeś. Kolejny że wolę to, aby utworzyć skrypt Pythona, gdzie można tworzyć wszystkie potrzebne dane i wykonać go w powłoce:

python manage.py shell < create_initial_data.py 
+2

Uwielbiam pomysł skryptu python, który sugerujesz! Ale na razie mam trochę za dużo danych, aby łatwo przekonwertować go do tego formatu. – achedeuzot

+0

Niepoprawne: ** automatyczne ładowanie ** urządzeń zostało wycofane w wersji 1.7. – Rainy

+1

Masz rację. Edytuję teraz odpowiedź. Dzięki! – ferrangb

Powiązane problemy