python - 如何在 Django 中使用 ContentType 外键上的 get_by_natural_key() 加载数据装置?

标签 python django json

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

我在模型中使用管理器,就像文档所说的那样。不幸的是,尽管文档讨论了 ContentType 外键上的 get_by_natural_key 方法的重要性,但它随后却启动了一个不同的示例。我很难弄清楚经理到底是什么样子。我最好的猜测是再次使用 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()

最佳答案

Django 中的自然键是

The default serialization strategy for foreign keys and many-to-many relations is to serialize the value of the primary key(s) of the objects in the relation.

对于那些在要转储的目标中不作为ForeignKey/ManyToManyField 出现的模型,您不需要在Manager 中实现natural_key 和get_by_natural_key 等方法。因此您可以删除 InlineTypeManager() 行。

此外,转储的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"]'

关于python - 如何在 Django 中使用 ContentType 外键上的 get_by_natural_key() 加载数据装置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9891148/

相关文章:

python - 词典理解查询

python - 两个长列表之间的最长公共(public)子串

ruby-on-rails - 有没有替代 Django 的 Rails Assets 管道?

python - 如何在 python 中反序列化 json 对象中的日期时间?

java - 从 JSON 文件中获取随机字符串

C# 相当于 Python 中的 "value error"

python - 访问 gtk.TreeIter 里面的 render() 函数的 gtk.CellRenderer -- pygtk

Django - 覆盖的表单 save() 方法返回 None?

python - Django 从apache 获取环境变量

javascript - 解析 JSON 时出现问题