用于自定义排序关系的 Django 管理小部件
我需要一些帮助来设计自定义排序的 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 pk
s 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 pk
s 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我会选择第一个选择。第二个似乎需要做很多工作,但收获却很少(如果有的话)。
当我需要一些明确的排序时,我总是在数据库中使用“权重”列。
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.