ecb*_*tln 17 django django-models django-admin
这就是我的模型的样子:
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')
Run Code Online (Sandbox Code Playgroud)
我真正想做的就是在创建给定的多人关系时添加时间戳.这很有意义,但它也增加了一些复杂性.除了删除.add()功能之外[尽管事实上我真正添加的唯一字段是自动创建的,所以它在技术上不应该再干扰它了].但我可以忍受这一点,因为我不介意做额外的事情,QuestionTagM2M.objects.create(question=,tag=)如果这意味着获得额外的时间戳功能.我的问题是我真的很想能够filter_horizontal在管理员中保存我的javascript小部件.我知道文档说我可以用内联代替,但因为没有其他字段实际上是内联除了外键,这是太笨重Tag反正.此外,在我的数据库模式的更大方案中,我的Question对象已经在我的管理页面上显示为内联,并且由于Django不支持admin [yet]中的嵌套内联,我无法为给定的选择标记题.有没有办法覆盖formfield_for_manytomany(self, db_field, request=None, **kwargs)或类似的东西允许我使用漂亮的filter_horizontal小部件和自动创建date_added列到数据库?这似乎是django应该能够本地执行的东西,只要您指定中间的所有列都是自动创建的(除外键之外)可能与auto_created=True?或类似的东西
有办法做到这一点
QuestionTagM2M._meta.auto_created = True和处理w/syncdb很重要.在models.py中动态地将date_added字段添加到模型的M2M模型中Question
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')
Run Code Online (Sandbox Code Playgroud)
然后你可以正常使用它在管理员ManyToManyField.
在Python shell中,用于Question.tags.through引用M2M模型.
注意,如果你不使用South,那就syncdb足够了; 如果这样做,South不喜欢这种方式并且不会冻结date_added字段,则需要手动编写迁移以添加/删除相应的列.
自定义ModelAdmin:
fields在自定义的ModelAdmin中定义,只定义filter_horizontal.这将绕过Irfan回答中提到的现场验证.formfield_for_dbfield()或formfield_for_manytomany()使Django管理员widgets.FilteredSelectMultiple用于该tags字段.save_related()在ModelAdmin类中自定义方法,比如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)
Run Code Online (Sandbox Code Playgroud)
__set__()的的ReverseManyRelatedObjectsDescriptorManyToManyField的现场描述符date_added,以节省M2M例如W/O引发异常.