python - 透明地将 Django 模型字段存储为 JSON 数据

标签 python django model

假设我有一个对象“Order”,它的一个字段“items”包含一个订单项目列表。永远不会在数据库中搜索或单独选择项目列表,因此我只想将其作为 JSON 字符串存储在数据库字段中。

我正在尝试找出嵌入此功能的最佳方式,以便它对使用该模型的任何人都相当透明。我认为保存模型非常简单 - 只需重写保存方法并将“items”列表序列化为内部“_items”字段,然后将其写入数据库。不过,我对如何反序列化感到困惑。在研究了可能用于创建的某种类方法,或者创建自定义管理器,或者与信号有关的东西之后,我彻底混淆了自己。我敢肯定这已经被解决了一百多次而且我很好奇人们认为什么是最佳实践。

示例类:

class OrderItem():
    def __init__(self, desc="", qty=0):
        self.desc = desc
        self.qty = qty


class Order(Model):
    user = ForeignKey(User)
    _items = TextField() 

    def save(self, *args, **kwargs):
        self._items = jsonpickle.encode(self.items)
        super(Order, self).save(*args, **kwargs)

示例用法:

order = Order()
order.items = [OrderItem("widget", 5)]
order.save()

这将在数据库中创建一条记录

_items = [{"desc":"widget", "qty":5}]

现在我希望以后能够选择对象

order = Order.objects.get(id=whatever)

并让 order.items 成为解压缩的项目数组,而不是存储的 JSON 字符串。

编辑:

事实证明,解决方案非常简单,我将其发布在这里,以防对其他新手有所帮助。根据 Daniel 的建议,我使用了这个自定义模型字段:

class JSONField(with_metaclass(SubfieldBase, TextField)):
    def db_type(self, connection):
        return 'JSONField'

    def to_python(self, value):
        if isinstance(value, basestring):
            return jsonpickle.decode(value)
        else:
            return value

    def get_prep_value(self, value):
        return jsonpickle.encode(value)

最佳答案

更好的方法是子类化 TextField 并覆盖相关方法以根据需要透明地执行序列化/反序列化。事实上,已经有很多这样的实现:here's one ,例如。

关于python - 透明地将 Django 模型字段存储为 JSON 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23409041/

相关文章:

python - 获取 Django 中所有唯一的 prefetch_lated 对象

mysql - 可以为 MySQL 修复数据库的 django 测试吗?

python - Tastypie 和 JSON Field 序列化问题

model - 您是否为 MVP 及其变体中的表示层购买了重用故事?

MVVM/WPF : Using a ObservableCollection<T> as a list in a domain model, 是好还是坏?

python - Visual Studio 代码窗口,Python Pandas 。没有名为 pandas 的模块

python - Python PyGTK 中进度条的最佳实践

python - pyenv activate 和 pyenv local 之间有区别吗?

python - opencensus 导出商 - 一个全局或每个线程?

php - 用Mysql将相同的内容 "type"存储在一张表中