django - django管理员使用through =和filter_horizo​​ntal的多对多中介模型

标签 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')


我真正想做的就是在创建给定的许多关系时添加一个时间戳。这很有意义,但同时也增加了一些复杂性。除了删除.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_horizo​​ntal的多对多中介模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10110606/

相关文章:

python - 如何从命令行查看我的 Postgres DB 架构

python - 将过滤后的列表传递给django中的模板后再次获取所有对象

python - Django Forbidden 403 Error "CSRF token missing or incorrect"已登录时尝试登录

python - 循环导入 django

Django 管理数据错误 : Value too long for type character varying(150)

Django 表单向导 - 将请求传递给 View ?

django - 如何以Django形式对外键关系的结果进行排序?

Django 在 save() 时自动压缩模型字段并在访问字段时解压缩

python - django:自动检测数据库上所做的 CRUD 更改

python - 如何在 Django 中使用用户 FK 为模型指定默认值