Django灯具保存默认值

时间:2014-09-08 12:30:18

标签: python django fixtures python-3.4 django-1.7

我正在使用Django 1.7,我的灯具有问题。

我希望Django使用默认值或使用save()方法创建未指定的值。

以下是我目前的对象:

# 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

如您所见,当我生成新的Post()时,会在created_at上自动创建updated_atuuidsave()值。但是当我使用灯具时,我收到以下错误:

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

如果我在fixture文件中指定了uuid,那么我会在created_at然后在updated_at上收到错误消息。所以我必须指定每个字段的内容,即使我希望它是“自动的”。

来自documentation(为什么这是django admin docs?!),我知道save()方法没有被调用,所以这就是为什么我放了进入save()方法不起作用。但是,defaultauto_now*功能不应该启用/使用吗?

  

处理夹具文件时,数据将按原样保存到数据库中。未调用模型定义的save()方法,并且将使用raw = True调用任何pre_save或post_save信号,因为实例仅包含模型本地的属性。例如,您可能希望禁用访问夹具加载期间不存在的相关字段的处理程序,否则会引发异常

有没有办法“强迫”Django自动使用defaultauto_now*功能用于灯具?我正在使用manage.py syncdb创建所有表格等。

我搜索了谷歌和堆栈溢出但似乎找不到合适的搜索关键字。

UPDATE-1 :以下google group discussion表示对象以raw模式保存,这意味着不会考虑auto_now*个功能。我仍然在寻找是否有办法将一些模型函数挂钩到Django夹具保存。

3 个答案:

答案 0 :(得分:5)

解决方案是使用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()

这样,模型/数据就会以你创建模型的方式填充(通过shell,fixture,等等)。

答案 1 :(得分:1)

Automatically loading initial data fixtures is deprecated in Django 1.7。一种解决方案是通过您提到的信号。 我更喜欢的另一个是创建一个python脚本,在其中创建所有需要的数据,并在shell中执行它:

python manage.py shell < create_initial_data.py

答案 2 :(得分:0)

我认为问题出在您放default=uuid.uuid4()时。括号太多了,因为它们暗示您将uuid.uuid4()的结果传递给默认参数,而不是函数本身,因此应将default=uuid.uuid4传递给