django - referencefield - querying database mongoengine
Django con problemas de almacenamiento Pluggable MongoDB (1)
Estoy tratando de usar django y mongoengine para proporcionar el backend de almacenamiento solo con GridFS. Todavía tengo una base de datos MySQL.
Me encuentro con un error extraño (para mí) cuando borro del administrador de django y me pregunto si estoy haciendo algo incorrectamente.
mi código se ve así:
# settings.py
from mongoengine import connect
connect("mongo_storage")
# models.py
from mongoengine.django.storage import GridFSStorage
class MyFile(models.Model):
name = models.CharField(max_length=50)
content = models.FileField(upload_to="appsfiles", storage=GridFSStorage())
creation_time = models.DateTimeField(auto_now_add=True)
last_update_time = models.DateTimeField(auto_now=True)
Puedo subir archivos muy bien, pero cuando los elimino, algo se rompe y la base de datos de Mongo parece estar en un estado impracticable hasta que elimine manualmente todos los FileDocument.objects. Cuando esto sucede, no puedo cargar archivos ni eliminarlos de la interfaz de django.
De la traza de pila tengo:
/home/projects/vector/src/mongoengine/django/storage.py in _get_doc_with_name
doc = [d for d in docs if getattr(d, self.field).name == name] ...
▼ Local vars
Variable Value
_[1]
[]
d
docs
Error in formatting: cannot set options after executing query
name
u''testfile.pdf''
self
/home/projects/vector/src/mongoengine/fields.py in __getattr__
raise AttributeError
¿Estoy usando esta característica incorrectamente?
ACTUALIZAR:
Gracias a la respuesta de @zeekay, pude conseguir que funcionara un complemento de almacenamiento de gridfs. Terminé sin usar mongoengine en absoluto. Puse mi solución adaptada en github . Hay un proyecto de muestra claro que muestra cómo usarlo. También subí el proyecto a pypi .
Otra actualización:
Recomiendo encarecidamente el proyecto django-storages . Tiene muchas opciones de almacenamiento respaldado y es utilizado por muchas más personas que mi solución propuesta original.
Creo que es mejor que no uses MongoEngine para esto, tampoco he tenido mucha suerte con eso. Aquí hay un reemplazo para mongoengine.django.storage.GridFSStorage
, que funciona con el administrador.
from django.core.files.storage import Storage
from django.conf import settings
from pymongo import Connection
from gridfs import GridFS
class GridFSStorage(Storage):
def __init__(self, host=''localhost'', port=27017, collection=''fs''):
for s in (''host'', ''port'', ''collection''):
name = ''GRIDFS_'' + s.upper()
if hasattr(settings, name):
setattr(self, s, getattr(settings, name))
for s, v in zip((''host'', ''port'', ''collection''), (host, port, collection)):
if v:
setattr(self, s, v)
self.db = Connection(host=self.host, port=self.port)[self.collection]
self.fs = GridFS(self.db)
def _save(self, name, content):
self.fs.put(content, filename=name)
return name
def _open(self, name, *args, **kwars):
return self.fs.get_last_version(filename=name)
def delete(self, name):
oid = fs.get_last_version(filename=name)._id
self.fs.delete(oid)
def exists(self, name):
return self.fs.exists({''filename'': name})
def size(self, name):
return self.fs.get_last_version(filename=name).length
GRIDFS_HOST
, GRIDFS_PORT
y GRIDFS_COLLECTION
pueden definirse en su configuración o pasarse como host
, port
, collection
argumentos de palabras clave a GridFSStorage
en el GridFSStorage
de su modelo.
Me referí a la documentación de almacenamiento personalizada de Django y seguí esta respuesta a una pregunta similar.