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

发布于 2024-10-02 01:53:42 字数 4720 浏览 4 评论 0原文

我需要一些帮助来设计自定义排序的 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)

,但随后出现一个问题:在 Publication 中制作一个易于使用的管理小部件是否可行?

2.解决方法:在 Publication 中创建一个 authors_order 字段,该字段采用一个带有允许用户重新排序的小部件的 pk 列表作者们。但这听起来有点棘手。

当然存在其他替代方案,并且欢迎提出建议。

I need some help at designing a model and widget for a custom-sorted M2M relationship. The typical application scenario would be books and authors. In particular, when the order of authors in a book does matter.

The current version of my Publication model is:

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]+)*

and authors are of People class:

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)

I have two possibilities for storing the order of authors for each publication:

1. Explicit: make a AuthorForPublication model

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

but then a question arise: is it feasible to make an easy to use admin widget into Publication?

2. Workaround: create an authors_order field in Publication that takes a list of pks with a widget that lets the user re-order the authors. But this sounds a bit tricky.

Other alternatives certainly exist and are suggestions are appreciated.

)]) 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)

and authors are of People class:

I have two possibilities for storing the order of authors for each publication:

1. Explicit: make a AuthorForPublication model

but then a question arise: is it feasible to make an easy to use admin widget into Publication?

2. Workaround: create an authors_order field in Publication that takes a list of pks with a widget that lets the user re-order the authors. But this sounds a bit tricky.

Other alternatives certainly exist and are suggestions are appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

生寂 2024-10-09 01:53:42

我会选择第一个选择。第二个似乎需要做很多工作,但收获却很少(如果有的话)。

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

I'd go for the first option. The second seems like a lot of work for very little (if any) gain.

When I need to have some explicit ordering, I always use a 'weight' column in the database.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文