用于自定义排序关系的Django管理小部件

时间:2010-11-15 09:35:30

标签: django django-admin many-to-many django-widget

我需要一些帮助,为自定义排序的M2M关系设计模型和小部件。典型的应用场景是书籍和作者。特别是,当书中作者的顺序很重要时。

我的Publication模型的当前版本是:

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)

作者属于People类:

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)

我有两种存储每个出版物的作者顺序的可能性:

1。明确:制作AuthorForPublication模型

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

然后出现了一个问题:将一个易于使用的管理窗口小部件用于发布是否可行?

2。解决方法:authors_order中创建一个Publication字段,其中包含pk个列表,其中包含允许用户重新排序作者的窗口小部件。但这听起来有点棘手。

当然存在其他替代方案,我们对此表示赞赏。

1 个答案:

答案 0 :(得分:0)

我会选择第一个选项。对于很少(如果有的话)获得,第二个似乎很多工作。

当我需要一些明确的排序时,我总是在数据库中使用'weight'列。