Django固定装置以默认值保存 [英] Django fixtures save with default value

查看:65
本文介绍了Django固定装置以默认值保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Django 1.7,但我的装置存在问题.

I'm using Django 1.7 and I have a problem with my fixtures.

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

I would like Django to use the default value or use the save() method to create unspecified values.

这是我当前的对象:

# 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()上自动创建的.但是当我使用灯具时,出现以下错误:

As you can see, when I generate a new Post(), the created_at, updated_at and uuid values are automatically created on save(). But when I use fixtures, I get the following error:

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

如果我在我的灯具文件中指定了 uuid ,那么我会在 created_at updated_at 上收到错误消息.因此,即使我希望它是自动的",我也必须指定每个字段的内容.

If I specify a uuid in my fixture file, then I get an error on created_at and then on updated_at. So I have to specify the content of each field, even though I want it to be "automatic".

文档(为什么在django中 admin docs?!),我知道未调用 save()方法,所以这就是为什么我将所有内容放入 save()方法的原因不起作用.但是不应该启用/使用 default auto_now * 功能吗?

From the documentation (why is this in the django admin docs ?!), I know that the save() method is not called so this is why everything I put into the save() method doesn't work. But shouldn't the default or auto_now* features be enables/used ?

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

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

有没有一种方法可以强制" Django自动使用灯具的 default auto_now * 功能?我正在使用 manage.py syncdb 创建所有表等.

Is there a way to "force" Django to automatically use the default or auto_now* features for fixtures ? I'm using manage.py syncdb to create all the tables etc.

我已经在google上搜索并且堆栈溢出,但是似乎找不到正确的搜索关键字.

I have searched on google and stack overflow but couldn't seem to find the right search keywords.

UPDATE-1 :以下 google小组讨论说,对象以 raw 模式保存,这意味着不考虑 auto_now * 功能.我仍在寻找是否有办法将某些模型函数与Django夹具保存挂钩.

UPDATE-1: The following google group discussion says that objects are saved in raw mode, meaning that auto_now* features are not taken into account. I'm still searching to see if there is a way to hook some model function to the Django fixture saving.

推荐答案

解决方案是使用Django信号:

The solution was to use django signals:

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

这样,无论您使用哪种方式创建模型,都可以通过外壳,固定装置等填充模型/数据.

That way, the model/data is populated whatever way you create the model (via shell, fixtures, whatever).

这篇关于Django固定装置以默认值保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆