私のモデルでは、トリプレットのリストを持つフィールドが必要です。例えば[[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]]
。このデータをデータベースに保存できるフィールドはありますか?
JSONを使用して文字列に変換し、文字列として保存できます。
例えば、
In [3]: json.dumps([[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]])
Out[3]: '[[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]]'
クラスにメソッドを追加して、自動的に変換することができます。
import json
class Foobar(models.Model):
foo = models.CharField(max_length=200)
def set_foo(self, x):
self.foo = json.dumps(x)
def get_foo(self):
return json.loads(self.foo)
Django 1.9とpostgresqlを使用している場合、JSONFieldという新しいクラスがあります。代わりに使用する必要があります。 ここにリンクがあります
youtube で、PostgreSQLのJSONと配列に関する良い話があります。それを見て、それは非常に良い情報を持っています。
PostgreSQLを使用している場合、ネストされたArrayFieldでArrayFieldを使用できます。 https://docs.djangoproject.com/en/2.2/ref/contrib/postgres/fields/
このようにして、データ構造は基礎となるデータベースに認識されます。また、ORMは特別な機能を提供します。
ただし、自分でGINインデックスを作成する必要があることに注意してください(上記のリンクを参照してください: https://docs.djangoproject.com/en/2.2/ref/contrib/postgres/fields/# indexing-arrayfield )。
(編集:最新のDjango LTSへの更新されたリンク。この機能は少なくとも1.8以降に存在します。)
1.10のようなDjangoのより新しいバージョンを使用していて、DBがPostgresである場合、Django-taggitまたは他の代替手段よりも使用するのが適切な新しい ArrayField があります。 Djangoフレームワークにネイティブであるため。
from Django.db import models
from Django.contrib.postgres.fields import ArrayField
class ChessBoard(models.Model):
board = ArrayField(
ArrayField(
models.CharField(max_length=10, blank=True),
size=8,
),
size=8,
)
役立つと思います。
Django.dbからモデルをインポート import ast class ListField(models.TextField): __metaclass__ = models.SubfieldBase description =「pythonリストを保存する」 def __init __(self、* args、** kwargs): super(ListField、self)。 __init __(* args、** kwargs) def to_python(self、value): if not value: value = [] if isinstance(value、list): return value return ast.literal_eval(value) def get_prep_value( self、value): 値がNoneの場合: return value return unicode(value) def value_to_string( self、obj): value = self._get_val_from_obj(obj) return self.get_db_prep_value(value) class ListModel(models.Model): test_list = ListField()
例:
>>> ListModel.objects.create(test_list = [[1,2,3]、[2,3,4,4]]) >>> ListModel .objects.get(id = 1) >>> o = ListModel.objects.get(id = 1) >>> o.id 1L >>> o.test_list [[1、2、3]、[2、3、4、4]] >>>
これらのサードパーティパッケージが提供するJSONフィールドを使用するだけです。
この場合、フィールド値のシリアル化を気にする必要はありません-内部で発生します。
お役に立てば幸いです。
リストをフラット化し、値を CommaSeparatedIntegerField に保存できます。データベースから読み戻すときは、値を3つにグループ化するだけです。
免責事項:データベースの正規化理論によれば、コレクションを単一のフィールドに保存しない方が良いです。代わりに、それらのトリプレットの値を独自のフィールドに保存し、外部キーを介してリンクすることをお勧めします。しかし、現実の世界では、それが面倒すぎる/遅い場合があります。
これはかなり古いトピックですが、「Djangoリストフィールド」を検索すると返されるので、Django 3および_で動作するように変更したカスタムPythonリストフィールドコードを共有します。Django 2.現在、管理インターフェースをサポートしており、evalを使用していません(これはPrashant Gaurのコードにおける大きなセキュリティ違反です)。
from Django.db import models
from typing import Iterable
class ListField(models.TextField):
"""
A custom Django field to represent lists as comma separated strings
"""
def __init__(self, *args, **kwargs):
self.token = kwargs.pop('token', ',')
super().__init__(*args, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
kwargs['token'] = self.token
return name, path, args, kwargs
def to_python(self, value):
class SubList(list):
def __init__(self, token, *args):
self.token = token
super().__init__(*args)
def __str__(self):
return self.token.join(self)
if isinstance(value, list):
return value
if value is None:
return SubList(self.token)
return SubList(self.token, value.split(self.token))
def from_db_value(self, value, expression, connection):
return self.to_python(value)
def get_prep_value(self, value):
if not value:
return
assert(isinstance(value, Iterable))
return self.token.join(value)
def value_to_string(self, obj):
value = self.value_from_object(obj)
return self.get_prep_value(value)
私の現在の評判では、コメントする能力がないので、 reply by Prashant Gaur のサンプルコードのコメントを参照する回答を選択します(ありがとう、Gaur-これは役に立ちました!)- python3にはないので、彼のサンプルはpython2用です
ユニコード
機能のための以下の置換
get_prep_value(self、value):
encoding = 'utf-8'、errors = 'ignore'
decode()
unicode()メソッド
errors = 'ignore'
import sys ... def get_prep_value(self、value): 値がNoneの場合: return value if sys.version_info [0]> = 3: if isinstance(out_data、type(b '')): return value.decode(encoding = 'utf-8'、errors = 'ignore') else: if isinstance(out_data、type(b '')): return unicode(value、encoding = 'utf-8'、errors = 'ignore') return str(value) ...
バックエンドとしてGoogle App EngineまたはMongoDBを使用しており、djangoappengine
ライブラリを使用している場合、組み込みのListField
があり、これはまさに必要なことを行います。さらに、リスト内の要素を含むすべてのオブジェクトを見つけるために、リストフィールドを照会するのは簡単です。