Pergunta

Primeiro, vou estabelecer o que estou tentando alcançar caso haja uma maneira diferente de fazer isso!

Quero poder editar os dois lados de um relacionamento M2M (de preferência na página de administração, embora, se necessário, possa estar em uma página normal) usando qualquer uma das interfaces multi -selecionadas.

O problema obviamente vem com o verso, pois o lado principal (onde o relacionamento é definido) funciona muito bem automaticamente.

Eu tentei alguns conselhos aqui para obter uma altura para aparecer e isso funciona, mas não é uma interface muito agradável.

O conselho que recebi na lista de discussão do Django foi usar um modelform personalizado. Eu tenho o ponto de aparecer uma caixa multisselect, mas não parece estar "conectada" a nada, pois não começa com nada selecionado e não salva nenhuma alteração feita.

Aqui estão os trechos de código apropriados:

#models.py
class Tag(models.Model):
    name = models.CharField(max_length=200)

class Project(models.Model):
    name = models.CharField(max_length=200)
    description = models.TextField()
    tags = models.ManyToManyField(Tag, related_name='projects')

#admin.py
class TagForm(ModelForm):
    fields = ('name', 'projects')
    projects = ModelMultipleChoiceField(Project.objects.all(), widget=SelectMultiple())
    class Meta:
        model = Tag

class TagAdmin(admin.ModelAdmin):
    fields = ('name', 'projects')
    form = TagForm

Qualquer ajuda seria muito apreciada, ou o código acima funcionaria ou fornecendo uma maneira melhor de fazê -lo!

Davidm

Foi útil?

Solução

A razão pela qual nada acontece automaticamente é que o campo "Projetos" não faz parte do modelo de tag. O que significa que você precisa fazer todo o trabalho sozinho. Algo como (no tagform):

def __init__(self, *args, **kwargs):
    super(TagForm, self).__init__(*args, **kwargs)
    if 'instance' in kwargs:
        self.fields['projects'].initial = self.instance.project_set.all()

def save(self, *args, **kwargs):
    super(TagForm, self).save(*args, **kwargs)
    self.instance.project_set.clear()
    for project in self.cleaned_data['projects']:
        self.instance.project_set.add(project)

Observe que o código não foi testado, então você pode precisar de um pouco para que ele funcione.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top