Domanda

Abbiamo un app Django che contiene un elenco di articoli di giornale. Ogni articolo ha un rapporto M2M sia con un "portavoce", così come un "fermo" (società menzionata nell'articolo).

Al momento, la pagina articolo Aggiungi per la creazione di nuovi articoli è abbastanza vicino a quello che vogliamo -. È solo il titolo Django Admin, e stiamo usando filter_horizontal per l'impostazione dei due rapporti M2M

Il passo successivo è stato quello di aggiungere un campo "rating" come un campo di intermediario su ogni rapporto m2m.

Quindi, un esempio del nostro models.py

class Article(models.Model):
    title = models.CharField(max_length=100)
    publication_date = models.DateField()
    entry_date = models.DateField(auto_now_add=True)
    abstract = models.TextField() # Can we restrict this to 450 characters?
    category = models.ForeignKey(Category)
    subject = models.ForeignKey(Subject)
    weekly_summary = models.BooleanField(help_text = 'Should this article be included in the weekly summary?')
    source_publication = models.ForeignKey(Publication)
    page_number = models.CharField(max_length=30)
    article_softcopy = models.FileField(upload_to='article_scans', null=True, blank=True, help_text='Optionally upload a soft-copy (scan) of the article.')
    url = models.URLField(null=True, blank=True, help_text = 'Enter a URL for the article. Include the protocl (e.g. http)')
    firm = models.ManyToManyField(Firm, null=True, blank=True, through='FirmRating')
    spokesperson = models.ManyToManyField(Spokeperson, null=True, blank=True, through='SpokespersonRating')

    def __unicode__(self):
        return self.title

class Firm(models.Model):
    name = models.CharField(max_length=50, unique=True)
    homepage = models.URLField(verify_exists=False, help_text='Enter the homepage of the firm. Include the protocol (e.g. http)')

    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ['name']

class Spokeperson(models.Model):
    title = models.CharField(max_length=100)
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.first_name + ' ' + self.last_name

    class Meta:
        ordering = ['last_name', 'first_name']

class FirmRating(models.Model):
    firm = models.ForeignKey(Firm)
    article = models.ForeignKey(Article)
    rating = models.IntegerField()

class SpokespersonRating(models.Model):
    firm = models.ForeignKey(Spokesperson)
    article = models.ForeignKey(Article)
    rating = models.IntegerField()

Il problema qui è che una volta che cambiamo la nostra Azienda e il campo Portavoce a "attraverso" e gli intermediari di utilizzo, la nostra pagina Add articolo non ha un controllo filter_horizontal per aggiungere Aziende / rapporti portavoce per l'articolo - che scompaiono completamente. Non è possibile vedere affatto. Non ho idea perché questo è.

speravo per lì per essere un modo per continuare a utilizzare il fresco filter_horizontal widget per impostare il rapporto, e in qualche modo solo incorporare un altro campo di sotto di quella per impostare il rating. Tuttavia, non sono sicuro di come fare questo mentre ancora potendo contare su l'amministratore Django.

ho visto un interessante resoconto qui circa l'override un unico widget nella Django admin:

http://www.fictitiousnonsense.com/archives/22

Tuttavia, non sono sicuro se questo metodo è ancora valido, e io non sono sicuro di applicarlo a qui, con un FK a un modello intermedio (è fondamentalmente un inline allora?).

Sicuramente c'è un modo facile di fare tutto questo?

Saluti, Victor

È stato utile?

Soluzione

Il problema è che il metodo formfield_for_manytomany del admin in django.contrib.admin.options non restituisce un campo di modulo per i campi ManyToMany con un modello di intermediazione! http://code.djangoproject.com/browser /django/trunk/django/contrib/admin/options.py#L157

Si dovrebbe ignorare questo metodo nella ModelAdmin:

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None    # return something suitable for your needs here!
    db = kwargs.get('using')

    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top