2010-11-15 3 views
0

J'ai besoin d'aide pour concevoir un modèle et un widget pour une relation M2M personnalisée. Le scénario d'application typique serait les livres et les auteurs. En particulier, lorsque l'ordre des auteurs dans un livre est important.Widget d'administration Django pour une relation personnalisée triée

La version actuelle de mon modèle Publication est:

class Publication(models.Model): 
    """ 
    A scientific publication. 
    """ 
    class Meta: 
     verbose_name = _('Publication') 
     verbose_name_plural = _('Publications') 
     ordering = ['year',] 

    nickname = models.CharField(
     max_length=16, 
     help_text=_(
      'A mnemonic name that "idenfies" this publication.'\ 
       ' E.g., concept_drift. (lowcase letters and dashes only)'), 
     validators=[RegexValidator(regex=r'^[a-z]+(_[a-z]+)*$')]) 
    title = models.CharField(
     _('Title'), 
     max_length=1024) 
    year = models.CharField(
     max_length=4, 
     choices=YEARS, 
     help_text=_('Year of publication'), 
     db_index=True) 
    month = models.PositiveSmallIntegerField(
     choices=MONTHS, 
     db_index=True, 
     null=True, 
     blank=True) 
    authors = models.ManyToManyField(
     Person, 
     related_name='publications', 
     blank=True, 
     null=True) 
    attachment = FileBrowseField(
     _('Attachment'), 
     max_length=256, 
     format='File', 
     blank=True, 
     null=True) 
    notes = models.CharField(
     _('Notes'), 
     max_length=512, 
     help_text=_('Notes, e.g., about the conference or the journal.'), 
     blank=True, 
     null=True) 
    bibtex = models.TextField(
     verbose_name=_('BibTeX Entry'), 
     help_text=_('At this moment, the BibTeX is not parsed for content.'), 
     blank=True, 
     null=True) 
    abstract = models.TextField(
     _('Abstract'), 
     blank=True, 
     null=True) 
    fulltext = FileBrowseField(
     _('Fulltext'), 
     max_length=256, 
     format='Document', 
     blank=True, 
     null=True) 
    date_updated = models.DateField(
     _('Last updated on'), 
     auto_now=True, 
     db_index=True) 
    citation_key = models.SlugField(
     max_length=512, 
     editable=False, 
     db_index=True) 

    @models.permalink 
    def get_absolute_url(self): 
     return ('academic_publishing_publication',(), { 'object_id': self.id }) 

    def __unicode__(self): 
     return u'%s %s' % (
      self.title, 
      self.year) 

et les auteurs sont de People classe:

class Person(models.Model): 
    """ 
    A person in a research lab. 
    """ 
    class Meta: 
     verbose_name = _('Person') 
     verbose_name_plural = _('People') 
     ordering = [ 
      'rank', 
      'last_name', 
      'first_name', ] 

    affiliation = models.ManyToManyField(
     Organization, 
     blank=True, 
     null=True, 
     related_name='people') 
    public = models.BooleanField(
     verbose_name=_('Public?'), 
     help_text=_('Toggle visibility on public pages.'), 
     default=False) 
    current = models.BooleanField(
     help_text=_('Is he/she still in the group?'), 
     default=True) 
    rank = models.ForeignKey(
     Rank, 
     verbose_name=_('Academic Rank'), 
     related_name='people', 
     blank=True, 
     null=True) 
    first_name = models.CharField(
     _('First Name'), 
     max_length=64) 
    mid_name = models.CharField(
     blank=True, 
     null=True, 
     max_length=64) 
    last_name = models.CharField(
     _('Last Name'), 
     max_length=64) 
    e_mail = models.EmailField(
     _('E-mail'), 
     blank=True, 
     null=True) 
    web_page = models.URLField(
     _('Web page'), 
     blank=True, 
     null=True) 
    description = models.TextField(
     _('Description'), 
     blank=True, 
     null=True) 
    picture = FileBrowseField(
     _('Profile picture'), 
     max_length=200, 
     format='Image', 
     blank=True, 
     null=True) 

    @models.permalink 
    def get_absolute_url(self): 
     return ('academic_people_person_detail',(), {'object_id': self.pk}) 

    def __unicode__(self): 
     return u'%s' % self.name 

    def _get_name(self): 
     return u'%s %s' % (self.first_name, self.last_name) 
    name = property(_get_name) 

J'ai deux possibilités de stockage de l'ordre des auteurs pour chaque publication:

1. Explicite: faire un AuthorForPublication modèle

class AuthorForPublication(models.Model): 
    author = ForeignKey(Person) 
    order = SmallPositiveInteger() 
    publication = ForeignKey(Publication) 

mais alors une question se pose: est-il possible de faire un widget d'administration facile à utiliser dans la publication?

2. Solution: créer un champ authors_order dans Publication qui prend une liste de pk s avec un widget qui permet à l'réordonner utilisateur les auteurs. Mais cela semble un peu difficile.

D'autres alternatives existent certainement et sont des suggestions sont appréciées.

Répondre

0

J'irais pour la première option. La seconde semble beaucoup de travail pour un gain minime (voire nul).

Lorsque j'ai besoin d'un ordre explicite, j'utilise toujours une colonne 'poids' dans la base de données.

+0

@ izz-ad-din-ruhulessin, dans ce cas, quel widget utiliseriez-vous? – phretor

+0

Je voudrais un CommaSeparatedIntegerField et du JavaScript pour créer une interface utilisateur sympa. –

+0

@ izz-ad-din-ruhulessin avez-vous un pointeur pour cette "belle interface utilisateur"? :) J'irais pour des trucs complets, mais je suis toujours ouvert aux nouvelles idées. – phretor

Questions connexes