这是我的模型的样子:
class QuestionTagM2M(models.Model):
tag = models.ForeignKey('Tag')
question = models.ForeignKey('Question')
date_added = models.DateTimeField(auto_now_add=True)
class Tag(models.Model):
description = models.CharField(max_length=100, unique=True)
class Question(models.Model):
tags = models.ManyToManyField(Tag, through=QuestionTagM2M, related_name='questions')
我真正想做的就是在创建给定的许多关系时添加一个时间戳。这很有意义,但同时也增加了一些复杂性。除了删除.add()功能之外(尽管我真正添加的唯一字段是自动创建的,因此从技术上讲,它不再应该对此造成干扰)。但是我可以接受,因为我不介意做额外的
QuestionTagM2M.objects.create(question=,tag=)
,如果这意味着获得额外的时间戳功能。我的问题是我真的很希望能够在管理中保留我的
filter_horizontal
javascript小部件。我知道文档说我可以改用内联,但这太笨拙了,因为除了Tag
的外键之外,实际上没有任何其他字段会真正在内联中。另外,在我的数据库模式的更大方案中,我的
Question
对象已经作为内联显示在我的管理页面上,并且由于Django在admin中还不支持嵌套内联[尚未],因此我无法选择标签对于给定的问题。是否有任何方法可以覆盖
formfield_for_manytomany(self, db_field, request=None, **kwargs)
或类似的方法,以允许我使用漂亮的filter_horizontal
小部件以及自动将date_added
列自动创建到数据库?只要您指定中间件中的所有列(不是外键)都是自动创建的(也许使用
auto_created=True
),django似乎应该能够做得到。或类似的东西
最佳答案
有办法做到这一点
如@aasoleter在the comment below中所提供的:设置QuestionTagM2M._meta.auto_created = True
并处理syncdb问题。
将date_added
字段动态添加到models.py中Question
模型的M2M模型中
class Question(models.Model):
# use auto-created M2M model
tags = models.ManyToMany(Tag, related_name='questions')
# add date_added field to the M2M model
models.DateTimeField(auto_now_add=True).contribute_to_class(
Question.tags.through, 'date_added')
然后,您可以像普通
ManyToManyField
一样在admin中使用它。在Python Shell中,使用
Question.tags.through
引用M2M模型。注意,如果您不使用
South
,那么syncdb
就足够了;如果您这样做,South
不喜欢这样,不会冻结
date_added
字段,您需要手动编写迁移操作以添加/删除相应的列。自定义ModelAdmin:
不要在定制的ModelAdmin中定义
fields
,仅定义filter_horizontal
。这将绕过Irfan答案中提到的现场验证。自定义
formfield_for_dbfield()
或formfield_for_manytomany()
以使Django管理员将widgets.FilteredSelectMultiple
用于tags
字段。在您的ModelAdmin类中自定义
save_related()
方法,例如def save_related(self, request, form, *args, **kwargs):
tags = form.cleaned_data.pop('tags', ())
question = form.instance
for tag in tags:
QuestionTagM2M.objects.create(tag=tag, question=question)
super(QuestionAdmin, self).save_related(request, form, *args, **kwargs)
同样,您可以为
__set__()
修补ManyToManyField的ReverseManyRelatedObjectsDescriptor
字段描述符的date_added
,以保存M2M实例而不会引发异常。
关于django - django管理员使用through =和filter_horizontal的多对多中介模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10110606/