如何在Django中的ContentType外键上使用get_by_natural_key()加载数据夹具?

时间:2012-03-27 14:03:57

标签: python django json

我在为使用ContentType外键的模型加载外部数据夹具时遇到问题。

我正在模特中使用经理,就像文档说的那样。不幸的是,尽管文档讨论了get_by_natural_key方法对ContentType外键的重要性,但它会转而使用另一个例子。我无法弄清楚经理会是什么样子。我最好的猜测是再次使用get_by_natural_key并分配app_labelmodel次查找,但我可能会离开。

# models.py 
from django.db import models 
from django.contrib.contenttypes.models import ContentType 
from django.utils.translation import ugettext_lazy as _ 

class InlineTypeManager(models.Manager): 
    def get_by_natural_key(self, title, app_label, model): 
        return self.get(title=title, content_type=ContentType.objects.get_by_natural_key(app_label=content_type__name, model=content_type__id)) 

class InlineType(models.Model): 
    title = models.CharField(_("title"), max_length=255) 
    content_type = models.ForeignKey(ContentType, limit_choices_to={"model__in": ("Link", "Document", "Image", "Audio", "Video", "MediaSet", "Flash", "Testimonial")}) 

    objects = InlineTypeManager() 

    class Meta: 
        ordering  = ["title"] 
        verbose_name = _("inline type") 
        verbose_name_plural = _("inline types") 

    def __unicode__(self): 
        return u"%s" % (self.title) 

https://docs.djangoproject.com/en/dev/topics/serialization/#natural-keys

我的initial_data.json

[
    {
        "model": "inlines.inlinetype",
        "pk": 1,
        "fields": {
            "title": "Image",
            "content_type": "image"
        }
    }, {
        "model": "inlines.inlinetype",
        "pk": 2,
        "fields": {
            "title": "Video",
            "content_type": "video"
        }
    }
]

当我loaddata我的JSON时,我收到错误:

DeserializationError: [u"'image' value must be an integer."] 

get_by_natural_key的要点是在“人性化”查找中加载非整数字段,因为JSON中的硬编码ID是一个坏主意,因为它不可预测,所以我猜我的经理失败了。或者我应该使用get_for_model() / get_for_models()

1 个答案:

答案 0 :(得分:1)

Django中的自然键是

  

外键和多对多关系的默认序列化策略是序列化关系中对象的主键值。

对于那些在转储目标中不作为ForeignKey / ManyToManyField出现的模型,您无需在Manager中实现诸如natural_key和get_by_natural_key之类的方法。所以你可以删除InlineTypeManager()行。

此外,dumped initial_data.json中的content_type字段的值不正确。 Django只将列表视为自然键,像“image”这样的字符串仍然被视为代理键,并且因为无法成功强制转换为int而失败。正确的ContentType转储看起来像

from django.contrib.contenttypes.models import ContentType
from django.utils import simplejson

>>> simplejson.dumps(ContentType.objects.get(model='user').natural_key())
'["auth", "user"]'