Domanda

Per prima cosa mi lay out quello che sto cercando di realizzare nel caso ci sia un modo diverso di andare su di esso!

Voglio essere in grado di modificare entrambi i lati di una relazione M2M (preferibilmente sulla pagina di amministrazione, anche se se necessario potrebbe essere in una pagina normale) utilizzando una delle interfacce multi-selezionare.

Il problema viene ovviamente con il lato posteriore, come il lato principale (dove è definito il rapporto) funziona bene automagicamente.

Ho provato alcuni di questi consigli per ottenere una linea di apparire e che funziona, ma la sua non è una bella interfaccia.

Il consiglio che ottenuto sul Django mailing list è stato quello di utilizzare un ModelForm personalizzato. Ho fino ad ottenere una casella di selezione multipla di apparire, ma Non sembra essere "collegati" a qualsiasi cosa in quanto non inizia con qualsiasi cosa selezionata e non salva le modifiche apportate.

Ecco i frammenti appropriati di codice:

#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

Qualsiasi aiuto sarebbe molto apprezzato, sia ottenendo il codice qui sopra per lavoro o fornendo un modo migliore per farlo!

DavidM

È stato utile?

Soluzione

Il motivo per cui non succede nulla automaticamente è che il campo "progetti" non è una parte del modello Tag. Il che significa che si deve fare tutto il lavoro da soli. Qualcosa di simile (in 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)

Si noti che il codice non è testato in modo che potrebbe essere necessario ancora un po tweek per farlo funzionare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top