【发布时间】:2014-11-01 16:13:50
【问题描述】:
我使用的是 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_at 和uuid 值会自动在save() 上创建。但是当我使用固定装置时,我得到以下错误:
[...]initial_data.yaml': Could not load post.Post(pk=None): UNIQUE constraint failed: post_post.uuid
如果我在我的夹具文件中指定了一个uuid,那么我会在created_at 和updated_at 上得到一个错误。所以我必须指定每个字段的内容,即使我希望它是“自动的”。
从documentation(为什么这是在 django admin 文档中?!),我知道 save() 方法没有被调用,所以这就是为什么我把所有东西都放入 @987654336 @ 方法不起作用。但是不应该启用/使用default 或auto_now* 功能吗?
处理夹具文件时,数据按原样保存到数据库中。不调用模型定义的 save() 方法,并且任何 pre_save 或 post_save 信号都将使用 raw=True 调用,因为实例仅包含模型本地的属性。例如,您可能希望禁用访问在夹具加载期间不存在的相关字段的处理程序,否则会引发异常
有没有办法“强制” Django 自动使用 default 或 auto_now* 特性作为固定装置?我正在使用manage.py syncdb 创建所有表等。
我在 google 上搜索过堆栈溢出,但似乎找不到正确的搜索关键字。
UPDATE-1:以下google group discussion 表示对象以raw 模式保存,这意味着不考虑auto_now* 功能。我仍在寻找是否有办法将某些模型函数挂钩到 Django 夹具保存。
【问题讨论】:
-
你能用数据迁移代替夹具吗?如果您稍后通过模式迁移更改模型,这还有一个优势,即它们可以继续工作。
-
目前我的数据有点多,无法轻松切换到迁移。但我知道这是一种更好的方法。
-
一个关于初始开发期间迁移的好问题stackoverflow.com/questions/5021800/…
-
IIUC,夹具的想法是您将一些记录从数据库保存到夹具,然后再次将其加载到另一个(或新创建的)数据库。因此,您要问的是与固定装置的设计背道而驰,这就是您遇到问题的原因。如果你想创建 new 记录,标准的方法是有一个(非常简单的)脚本从某个地方抓取数据并以标准方式创建和保存记录,即 MyModel.create(**data )。
-
@Rainy 不也是用初始数据预填充数据库吗? (就我而言,这就是我使用它们的原因)
标签: python django fixtures python-3.4 django-1.7