2009-02-05 19 views
5

Tengo un par de modelos en django que están conectados de muchos a muchos. Quiero crear instancias de estos modelos en la memoria, presentarlos al usuario (a través de métodos personalizados-llamadas dentro de las plantillas de vista) y si el usuario está satisfecho, guardarlos en la base de datos.¿Cómo trabajar con relaciones de muchos a muchos no guardados en django?

Sin embargo, si trato de hacer algo en las instancias de modelo (métodos de representación de llamada, por ejemplo), aparece un mensaje de error que dice que primero tengo que guardar las instancias. La documentación dice que esto se debe a que los modelos están en una relación de muchos a muchos.

¿Cómo presento los objetos al usuario y le permite guardarlos o descartarlos sin saturar mi base de datos?

(supongo que podría desactivar las operaciones de manipulación, de ponerlos a mí mismo a lo largo de todo el proyecto, pero esto suena como una medida potencialmente propenso a errores ...)

Thx!

Respuesta

4

Creo que el uso de formularios django puede ser la respuesta, como se indica en la documentación this (búsqueda de m2m ...).

Editado para añadir un poco de explicación para otras personas que podrían tener el mismo problema:

que usted tiene un modelo como este:

from django.db import models 
from django.forms import ModelForm 

class Foo(models.Model): 
    name = models.CharField(max_length = 30) 

class Bar(models.Model): 
     foos = models.ManyToManyField(Foo) 

    def __unicode__(self): 
     return " ".join([x.name for x in foos]) 

entonces no se puede llamar a Unicode() sobre un objeto barra no guardado . Si desea imprimir las cosas antes de que se guardarán, hay que hacer esto:

class BarForm(ModelForm): 
    class Meta: 
     model = Bar 

def example():  
    f1 = Foo(name = 'sue') 
    f1.save() 
    f2 = foo(name = 'wendy') 
    f2.save() 
    bf = BarForm({'foos' : [f1.id, f2.id]}) 
    b = bf.save(commit = false) 
    # unfortunately, unicode(b) doesn't work before it is saved properly, 
    # so we need to do it this way: 
    if(not bf.is_valid()): 
     print bf.errors 
    else: 
     for (key, value) in bf.cleaned_data.items(): 
      print key + " => " + str(value) 

Por lo tanto, en este caso, tiene que haber salvado objetos Foo (que es posible validar antes de guardar los, usando su propia forma), y antes de guardar los modelos con muchas o muchas claves, puede validarlas también. Todo sin la necesidad de guardar datos demasiado pronto y estropear la base de datos o lidiar con transacciones ...

6

Agregaría un campo que indica si los objetos son "borrador" o "en vivo". De esa manera se persisten a través de solicitudes, sesiones, etc. y django deja de quejarse.

A continuación, puede filtrar los objetos para que solo muestren objetos "activos" en vistas públicas y solo muestren objetos "borrador" al usuario que los creó. Esto también se puede extender para permitir objetos "archivados" (o cualquier otro estado que tenga sentido).

0

Última respuesta, pero el equipo de wagtail ha hecho una extensión de Django por separado llamada django-modelcluster. Es lo que impulsa los avances preliminares del borrador de su CMS.

Se le permite hacer algo como esto (desde su README):

from modelcluster.models import ClusterableModel 
from modelcluster.fields import ParentalKey 

class Band(ClusterableModel): 
    name = models.CharField(max_length=255) 

class BandMember(models.Model): 
    band = ParentalKey('Band', related_name='members') 
    name = models.CharField(max_length=255) 

A continuación, los modelos pueden ser utilizados de esta manera:

beatles = Band(name='The Beatles') 
beatles.members = [ 
    BandMember(name='John Lennon'), 
    BandMember(name='Paul McCartney'), 
] 

Aquí, ParentalKey es el equivalente de Django de ForeignKey . Del mismo modo, tienen ParentalManyToManyField para reemplazar ManyToManyField de Django.

Cuestiones relacionadas