Como trabalhar com não salvos muitos-para-muitos relações em Django?

votos
5

Eu tenho um par de modelos no Django que estão ligados muitos-para-muitos. Eu quero criar instâncias destes modelos na memória , apresentá-los ao usuário (via personalizados método-chamadas dentro a exibição de modelos) e se o usuário está satisfeito, guardá-las para o banco de dados.

No entanto, se eu tentar fazer alguma coisa sobre o modelo de casos (chamada de renderização métodos, por exemplo), recebo uma mensagem de erro que diz que eu tenho que salvar as instâncias em primeiro lugar. A documentação diz que isso é porque os modelos estão em um relacionamento muitos-para-muitos.

Como faço para apresentar objetos para o usuário e permitindo que ele / ela para salvar ou descartá-las sem encher meu banco de dados?

(Eu acho que eu poderia desligar as operações de movimentação e fazê-los eu mesmo ao longo de todo o projeto, mas isso soa como uma medida potencialmente propensa a erros ...)

THX!

Publicado 05/02/2009 em 23:01
fonte usuário
Em outras línguas...                            


3 respostas

votos
6

Gostaria de acrescentar um campo que indica se os objetos são "rascunho" ou "ao vivo". Dessa forma, eles são persistentes entre solicitações, sessões, etc., e Django pára reclamando.

Você pode então filtrar os objetos para mostrar apenas objetos "ao vivo" em exibições públicas e único show "rascunho" objetos para o usuário que os criou. Isso também pode ser alargado para permitir que objetos "arquivados" (ou qualquer outro estado que faz sentido).

Respondeu 05/02/2009 em 23:34
fonte usuário

votos
4

Eu acho que o uso de formulários Django pode ser a resposta, conforme descrito na presente documentação (procurar m2m ...).

Editado para acrescentar alguma explicação para outras pessoas que possam ter o mesmo problema:

dizer que você tem um 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])

então você não pode chamar unicode () em um objeto Bar salvos. Se você deseja imprimir as coisas antes de eles serão salvos, você tem que fazer isso:

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)

Então, neste caso, você tem que ter salvo objetos Foo (que você pode validar antes de salvar aqueles que, usando sua própria forma), e antes de salvar os modelos com muitos para muitos chaves, você pode validar as também. Tudo sem a necessidade de guardar os dados muito cedo e estragar o banco de dados ou lidar com transações ...

Respondeu 06/02/2009 em 08:52
fonte usuário

votos
0

Muito resposta tardia, mas a equipe de wagtail tornou uma extensão de Django separado chamado django-modelcluster . É o que poderes projectos de visualizações do seu CMS.

Ele permite que você fazer algo assim (a partir de sua 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)

Em seguida, os modelos podem ser usados ​​assim:

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

Aqui, ParentalKeyé o substituto do Django ForeignKey. Da mesma forma, eles têm ParentalManyToManyFieldde substituir Django ManyToManyField.

Respondeu 23/09/2017 em 14:33
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more