[Python e Django] - ORM relacionamento ManyToManyField

Boa tarde pessoal,

estou com um problema na orm do django referente a relacionamentos “muitos para muitos”. Tenho duas tabelas, Cd e Cantor, e preciso fazer um relacionamento entre as duas, que seria CdCantor. Meu script está da seguinte forma:


create table VirtualStore.Cantor(
	id integer not null,
	nome varchar(50) not null,
	banda varchar(50) not null,
	constraint PK_Cantor primary key(id)
);


create table VirtualStore.Cd(
	id integer not null auto_increment,
	idGenero integer not null,
	idAnoLancamento integer not null,
	titulo varchar(50) not null,
	autor varchar(50) not null,
	descricao varchar(500),
	tipo enum('C','D') not null,
	constraint PK_Cd primary key(id),
	constraint FK_Cd_Genero foreign key(idGenero) references Genero(id),
	constraint FK_Cd_AnoLancamento foreign key(idAnoLancamento) references AnoLancamento(id)
	
);


create table VirtualStore.CdCantor(
	id integer not null auto_increment,
	idCd integer not null,
	idCantor integer not null,
	constraint PK_CdCantor primary key(id),
	constraint UK_CdCantor unique key(idCd, idCantor),
	constraint FK_CdCantor_Cd foreign key(idCd) references Cd(id),
	constraint FK_CdCantor_Cantor foreign key(idCantor) references Cantor(id)
);

Criei as classes Cd, Cantor e CdCantor, segue o código das 3 classes abaixo:


# -*- coding: utf-8 -*-
from django.db import models
from lojaVirtual.anoLancamento.models import AnoLancamento
from lojaVirtual.cantor.models import Cantor
from lojaVirtual.genero.models import Genero

class Cd (models.Model):
    id = models.AutoField(primary_key=True, db_column='id')
    titulo = models.CharField(max_length=50, db_column='titulo')
    autor = models.CharField(max_length=50, db_column='autor')
    descricao = models.TextField(db_column='descricao')
    anoLancamento = models.ForeignKey(AnoLancamento, db_column='idAnoLancamento')
    genero = models.ForeignKey(Genero, db_column='idGenero')
    cantor = models.ManyToManyField(Cantor, through='CdCantor')
    tipo = models.CharField(max_length=1, choices=(('C', 'CD'),('D', 'DVD')), db_column='tipo')
    
    class Meta:
        db_table = u'Cd'
        managed = False

class CdCantor (models.Model):
    id = models.AutoField(primary_key=True, db_column='id')
    idCd = models.ForeignKey(Cd, db_column='idCd')
    idCantor = models.ForeignKey(Cantor, db_column='idCantor')
    
    class Meta:
        db_table = u'CdCantor'
        unique_together = ('idCd','idCantor') 
        managed = False
# -*- coding: utf-8 -*-
from django.db import models

class Cantor(models.Model):
    id = models.AutoField(primary_key=True, db_column='id')
    nome = models.CharField(max_length = 50, db_column='nome')
    banda = models.CharField(max_length = 50, db_column='banda')

    def __unicode__ (self):
        return self.nome + " / " + self.banda 
    
    class Meta:
        db_table = u'Cantor'
        managed = False

Como já tenho a base pronta, não preciso usar o syncdb do Django, porém não consigo mapear a tabela CdCantor, na hora de salvar dá o seguinte erro.

Estou salvando direto do form:


def new(request):
    if request.method == "POST":
        form = CdForm(request.POST, request.FILES)
        
        if form.is_valid():
            cd = form.save()
            return sucess(request, cd)
    else:
        form = CdForm()
        
    return render_to_response("cd/cd.html", {'form': form}, context_instance=RequestContext(request))

Se eu gerar automaticamente, sem a classe CdCantor e colocar db_table=‘CdCantor’ ao invés de through=‘CdCantor’ e gerar a base usando syncdb, dá certo, mas não posso usar porque já tenho a base pronta.

Se alguém puder ajudar desde já agradeço.

Obrigado!

Falaí!

Vc pode postar o código do CdForm?

Você não pode salvar o relacionamento todo de uma vez só usando um manager intermediário.
Um caminho é salvar o CD e depois salvar o relacionamento dele com o cantor.