2010-11-10 12 views
6

Quiero crear un modelo que no se asocie a una tabla de base de datos. En cambio, se queda en la memoria como un objeto python.cómo crear un modelo Django que no se correlaciona con una tabla de base de datos

En realidad, se supone que este modelo representa datos normalizados de muchos otros modelos de tabla asignada.

Los otros modelos almacenan datos que se pueden editar varias veces en un solo día. Debido a estas ediciones múltiples, no quiero un modelo mapeado en tabla que realice normalizaciones/cálculos y los almacene en una base de datos, ya que estos datos almacenados pueden quedar desactualizados de inmediato.

Cada vez que se accede a este modelo normalizado (a través de admin), quiero realizar las normalizaciones de los datos desde los otros modelos desde cero (para que pueda mostrar los datos más actualizados) y comportarme como un normal modelo bajo administración como Mostrar la vista de lista y una vista detallada para cada fila.

Edición después de la respuesta de Shintoist:

Gracias @Shintoist de las cosas y la limpieza de proporcionar un enfoque útil. Acabo de implementarlo, pero al final toco un pequeño muro :)

@skirmantas: Sí, los cálculos están en un objeto separado. Este objeto se está pasando a las vistas personalizadas.

Problema: Un problema es que bajo admin.py, he creado un modeladminclass para este objeto (que no hereda models.Model) por lo que mis vistas personalizadas pueden sobreponerse a la vista de lista de cambios y a la vista de cambio. Luego uso admin.site.register() para registrar esta clase de modelo y modeladmin. Pero, dado que este modelo no es en absoluto un modelo de django (ya que es un objeto python independiente en la memoria) admin.site.register() arroja un error de "tipo" el objeto no es iterable ". No quiero usar el url.py en lugar de admin.py, ya que está destinado a la interfaz mientras trato de superar al administrador de backend.

+1

Entiendo que quiera usar el administrador, pero para sus necesidades es una forma muy redonda de hacerlo. ¿No podría simplemente anular la plantilla de administrador con un enlace en algún lugar de la página a la URL que utiliza la vista que escribió? De esa forma estaría "en" el administrador. Django buscará automáticamente plantillas que anulen las entradas integradas. De lo contrario, te sugiero que vayas con la solución de Tomasz Zielinski. –

+0

@tomas. Si creo el modelo de normalización para mapear a una tabla en la memoria, no sería aún estático. Quiero decir, el modelo cuando se abre, obtiene los últimos datos de otros modelos, normaliza/procesa esos datos y muestra una lista. Ahora, mientras tanto, si alguien edita los otros modelos, estos no se mostrarían en el modelo de normalización hasta que se reinicie el servidor (lo que recargaría la tabla de memoria). – sysasa

+0

También me gustaría añadir, mi implementación de django ya usa tres bases de datos, una que contiene datos heredados (para poder migrarla al nuevo sistema), una SQLlite para ejecutar pruebas a través de dispositivos y la tercera, la base de datos principal. Esto también significa que agregaré una cuarta base de datos solo por el solo modelo. – sysasa

Respuesta

0

hmmm. Gracias por su ayuda a todos.La solución que he llegado (con su ayuda por supuesto) es la siguiente:

que tienen dos plantillas personalizadas:

my_model_list.html 
    my_model_detail.html 

Bajo views.py:

class MyModel(object): 
    # ... Access other models 
    # ... process/normalise data 
    # ... store data 

@staff_member_required 
def my_model_list_view(request) #show list of all objects 
    #. . . create objects of MyModel . . . 
    #. . . call their processing methods . . . 
    #. . . store in context variable . . . 
    r = render_to_response('admin/myapp/my_model_list.html', context, RequestContext(request)) 
    return HttpResponse(r) 

@staff_member_required 
def my_model_detail_view(request, row_id) # Shows one row (all values in the object) in detail  
    #. . . create object of MyModel . . . 
    #. . . call it's methods . . . 
    #. . . store in context variable . . . 
    r = render_to_response('admin/myapp/my_model_detail.html', context, RequestContext(request)) 
    return HttpResponse(r) 

Bajo las principales direcciones URL django .py:

urlpatterns = patterns( 
    '', 
    (r'^admin/myapp/mymodel/$', my_model_list_view), 
    (r'^admin/myapp/mymodel/(\d+)/$', my_model_detail_view), 
    (r'^admin/', include(admin.site.urls)) 
) 

Como ya se ha notado, he tenido que insertar patrones de URL a mi archivo url.py. No sé si esa es la mejor manera de hacerlo, ya que considero que el archivo url.py no es para páginas relacionadas con el administrador. Es solo para la interfaz del sitio.

2

¿Por qué tener un modelo en absoluto? Haga referencia a sus cálculos en una vista, escriba una plantilla y requiera el inicio de sesión de administrador para acceder a ella. Eso recrearía estos datos normalizados solo cuando cargue la página y solo existiría en la memoria, lo que le ahorraría recursos.

+4

'Ponga sus cálculos en una vista' Eso es lo peor que podría hacer. Conseguirá un código ilegible y no se puede mantener. Las vistas deben ser minimalistas. Cualquier cálculo debe hacerse en otro lugar. Los formularios funcionan bien para analizar los datos de solicitud. Los cálculos se pueden hacer dentro de los ayudantes. – Ski

+1

aclarado para usted. –

+0

He editado mi pregunta. Por favor, mira arriba – sysasa

6

¿Qué ocurre con el uso de múltiples bases de datos y la configuración de una de ellas para usar tablas en memoria?

Para MySQL se vería así:

DATABASES = { 
    'default': { 
    }, 
    'memory': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'dbname', 
     'USER': 'dbuser', 
     'PASSWORD': '', 
     'HOST': 'localhost', 
     'PORT': '',   

     'OPTIONS': {"init_command": "SET storage_engine=MEMORY"} 
    } 
} 

Tenga en cuenta que sólo tendrá que utilizar SET storage_engine al crear tablas, pero podría ser que no se le añade demasiada sobrecarga de todos modos para su caso de uso.

http://dev.mysql.com/doc/refman/5.0/en/memory-storage-engine.html

+0

me ganaste al golpe. Aunque lo hubiera hecho en SQLite. – JudoWill

+0

@JudoWill: Correcto, SQLite también es un camino por recorrer. Personalmente, prefiero usar el mismo DBMS para todo el trabajo, solo para mantenerme seguro en caso de algunas incompatibilidades. Esto, sin embargo, se refiere principalmente a pruebas unitarias. –

+0

Si creo el modelo de normalización para asignarlo a una tabla en la memoria, aún no sería estático. Quiero decir, el modelo cuando se abre, obtiene los últimos datos de otros modelos, normaliza/procesa esos datos y muestra una lista. Ahora, mientras tanto, si alguien edita los otros modelos, estos no se mostrarían en el modelo de normalización hasta que se reinicie el servidor (lo que recargaría la tabla de memoria) – sysasa

1

Dependiendo de la complejidad de estos "cálculos" son, parece que desea una costumbre database view (apoyado, creo, por SQLite, MySQL, PostgreSQL y Oracle, al menos) que se utiliza en conjunción con un modelo con Meta.managed=False.

Si tiene suerte, podrá obtener South para crearlo para usted en una migración, pero aún no parece que South admita vistas.

Cuestiones relacionadas