Я даже не уверен, возможно ли это, поэтому думаю, что мой вопрос двоякий. Во-первых, возможно ли это? Во-вторых, если это не так, пока данные доступны только для чтения, могут ли возникнуть какие-либо серьезные проблемы, если я позволю входным данным быть пустым массивом, а выходным — json.
Настраиваемое поле определяется так:
Используемые пакеты:
Код: Выделить всё
import io
import json
import numpy as np
from django.db.models import BinaryField
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
Код: Выделить всё
# Stores numpy array as BLOB then returns BLOB as np array
class NpArrayField(BinaryField):
"""
Turns numpy array into raw binary data to store in database. When take from database, it outputs the numpy array.
"""
def from_db_value(self, value, expression, connection):
if value is None:
return None
buffer = io.BytesIO(value)
return np.load(buffer, allow_pickle=True) # returns numpy array
def to_python(self, value):
if value is None or isinstance(value, np.ndarray):
return value
# If it's bytes from DB or form
if isinstance(value, (bytes, bytearray)):
buffer = io.BytesIO(value)
return np.load(buffer, allow_pickle=True)
raise ValidationError(_("NpArrayField value must be a numpy.ndarray or a byte/bytearray"))
def get_prep_value(self, value):
if value is None:
return None
if not isinstance(value, np.ndarray):
raise ValidationError(_("NpArrayField value must be a numpy.ndarray"))
buffer = io.BytesIO()
np.save(buffer, value, allow_pickle=True)
return buffer.getvalue()
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
return name, path, args, kwargs
Код: Выделить всё
class NpArrayEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, numpy.ndarray):
return obj.tolist()
return json.JSONEncoder.default(self,obj)
class NpArrayField(BinaryField):
"""
Turns numpy array into json style raw binary data to store in database. When taken from the database, it outputs the json
"""
def from_db_value(self, value, expression, connection):
if value is None:
return None
return value.decode('utf-8'))
def to_python(self, value):
if value is None:
return None
return value
def get_prep_value(self, value):
if value is None:
return None
if not isinstance(value, np.ndarray):
raise ValidationError(_("NpArrayField value must be a numpy.ndarray"))
np_as_json = json.dumps({"array" : value}, cls=NpArrayEncoder)
return bytes(np_as_json, 'utf-8')
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
return name, path, args, kwargs
Подробнее здесь: https://stackoverflow.com/questions/798 ... ile-asking
Мобильная версия