Ati*_*nch 50 python django orm persistence django-models
我需要在Django模型中存储一些数据.这些数据不等于模型的所有实例.
起初我考虑过继承模型,但我试图保持应用程序的灵活性.如果我使用子类,每次需要一种新的对象时我都需要创建一个完整的类,这并不好.我最终会得到很多子类来存储一对额外的字段.
我真的觉得字典是最好的方法,但Django文档中没有关于在Django模型中存储字典(或者我找不到它)的内容.
有线索吗?
Par*_*and 38
如果它真的像你正在寻找的任意数据字典,你可以使用一个两级设置,一个模型是一个容器,另一个模型是键值对.您将创建容器的实例,创建每个键值实例,并将键值实例集与容器实例相关联.就像是:
class Dicty(models.Model):
name = models.CharField(max_length=50)
class KeyVal(models.Model):
container = models.ForeignKey(Dicty, db_index=True)
key = models.CharField(max_length=240, db_index=True)
value = models.CharField(max_length=240, db_index=True)
Run Code Online (Sandbox Code Playgroud)
它不漂亮,但它会让你使用数据库访问/搜索字典的内部,而pickle/serialize解决方案则不会.
Ned*_*der 15
如果您不需要通过任何这些额外数据进行查询,则可以将其存储为序列化字典.使用repr打开字典成一个字符串,并eval把字符串返回到一本字典.注意eval,字典中没有用户数据,或者使用safe_eval实现.
Sté*_*ane 11
我通过google的4rth结果来到这个帖子"django store object"
有点晚了,但是django-picklefield对我来说看起来很好.
来自doc的示例:
要使用,只需在模型中定义一个字段:
>>> from picklefield.fields import PickledObjectField
>>> class SomeObject(models.Model):
>>> args = PickledObjectField()
Run Code Online (Sandbox Code Playgroud)
并将任何你喜欢的东西(只要它可以选择)分配到该字段:
>>> obj = SomeObject()
>>> obj.args = ['fancy', {'objects': 'inside'}]
>>> obj.save()
Run Code Online (Sandbox Code Playgroud)
ode*_*fos 11
另一个干净,快速的解决方案可以在这里找到:https://github.com/bradjasper/django-jsonfield
为方便起见,我复制了简单的说明.
安装
pip install jsonfield
Run Code Online (Sandbox Code Playgroud)
用法
from django.db import models
from jsonfield import JSONField
class MyModel(models.Model):
json = JSONField()
Run Code Online (Sandbox Code Playgroud)
正如Ned所说,如果你使用字典方法,你将无法查询"某些数据".
如果你仍然需要存储词典,那么到目前为止,最好的方法是在Marty Alchin的新书Pro Django中记录的PickleField类.此方法使用Python类属性仅在需要时对存储在模型字段中的python对象进行pickle/unpickle.
这种方法的基础是使用django的contibute_to_class方法动态地向模型添加新字段,并使用getattr/setattr按需进行序列化.
我能找到的为数不多的在线示例之一就是JSONField的这个定义.
这个问题很旧,但我遇到了同样的问题,到此结束,选择的答案无法再解决我的问题。
如果您想在 Django 或 REST Api 中存储字典,或者用作前端的对象,或者因为您的数据不一定具有相同的结构,我使用的解决方案可以帮助您。
在 API 中保存数据时,请使用json.dump()方法以正确的 json 格式存储数据,如本问题所述。
如果您使用此结构,您的数据将已经采用适当的 json 格式,以便在前端使用ajax(或其他)调用中的JSON.parse()进行调用。
我不确定你要解决的问题的性质,但它听起来与谷歌应用引擎的BigTable Expando很奇怪.
Expandos允许您在运行时在数据库支持的对象实例上指定和存储其他字段.引用文档:
import datetime
from google.appengine.ext import db
class Song(db.Expando):
title = db.StringProperty()
crazy = Song(title='Crazy like a diamond',
author='Lucy Sky',
publish_date='yesterday',
rating=5.0)
crazy.last_minute_note=db.Text('Get a train to the station.')
Run Code Online (Sandbox Code Playgroud)
Google App Engine目前支持Python和Django框架.如果这是表达模型的最佳方式,可能值得研究.
传统的关系数据库模型没有这种列添加灵活性.如果您的数据类型足够简单,您可以打破传统的RDBMS原则,并通过序列化将值破解为单个列,如@Ned Batchelder所建议的那样; 但是,如果你必须使用RDBMS,那么Django模型继承可能就是这样.值得注意的是,它将为每个派生级别创建一对一的外键关系.
我使用文本字段和json.loads()/json.dumps()
models.py
import json
from django.db import models
class Item(models.Model):
data = models.TextField(blank=True, null=True, default='{}')
def save(self, *args, **kwargs):
## load the current string and
## convert string to python dictionary
data_dict = json.loads(self.data)
## do something with the dictionary
for something in somethings:
data_dict[something] = some_function(something)
## if it is empty, save it back to a '{}' string,
## if it is not empty, convert the dictionary back to a json string
if not data_dict:
self.data = '{}'
else:
self.data = json.dumps(data_dict)
super(Item, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
我知道这是一个老问题,但今天(2021)最干净的替代方案是使用原生 JSONfield (自 django 3.1 起)
\n文档:https://docs.djangoproject.com/en/3.2/ref/models/fields/#django.db.models.JSONField
\n您只需在类模型内的模型中创建一个名为 jsonfield 的字段,然后 voil\xc3\xa1
\n| 归档时间: |
|
| 查看次数: |
46600 次 |
| 最近记录: |