Question

Nous avons une application Django qui contient une liste d'articles de journaux. Chaque article a une relation m2m à la fois un « porte-parole », ainsi qu'une « entreprise » (société mentionnée dans l'article).

À l'heure actuelle, la page Ajouter un article pour la création de nouveaux articles est assez proche de ce que nous voulons -. Il est juste le stock Django Admin, et nous utilisons filter_horizontal pour définir les deux relations m2m

L'étape suivante a consisté à ajouter un champ « rating » comme un champ intermédiaire sur chaque relation m2m.

Ainsi, un exemple de notre 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()

La question ici est qu'une fois que nous changeons notre entreprise et sur le terrain de porte-parole de « grâce » et les intermédiaires d'utilisation, notre Ajouter article page ne dispose d'un contrôle filter_horizontal ajouter Entreprises / relations spokeperson à l'article - ils disparaissent complètement. Vous ne pouvez pas les voir du tout. Je ne sais pas pourquoi.

J'espérais pour qu'il y ait un moyen de continuer à utiliser le widget filter_horizontal cool de mettre la relation, et en quelque sorte juste embed un autre champ ci-dessous que pour régler la note. Cependant, je ne suis pas sûr de savoir comment faire cela tout en tirant parti encore hors administration de Django.

J'ai vu un writeup ici au sujet de la suppression d'un seul widget dans l'admin Django:

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

Cependant, je ne sais pas si cette méthode est toujours valide, et je ne suis pas sûr de l'appliquer ici, avec un FK à un modèle intermédiaire (il est essentiellement une ligne alors?).

Certes, il y a un moyen facile de faire tout cela?

Cordialement, Victor

Était-ce utile?

La solution

Le problème est que la méthode d'administration de formfield_for_manytomany dans django.contrib.admin.options ne retourne pas un champ de formulaire pour les champs ManyToMany avec un modèle intermédiaire! http://code.djangoproject.com/browser /django/trunk/django/contrib/admin/options.py#L157

Vous devrait remplacer cette méthode dans votre 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))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top