【问题标题】:Limit Django's inlineformset_factory to only create new objects将 Django 的 inlineformset_factory 限制为仅创建新对象
【发布时间】:2011-01-22 06:27:01
【问题描述】:

我正在使用 django 的内联表单集工厂。要使用文档中的示例,

author = Author.objects.get(pk=1)
BookFormSet = inlineformset_factory(Author, Book)
formset = BookFormSet(request.POST, instance=author)

将创建一个内联表单集来编辑特定作者的书籍。

我想创建一个表单集,只允许用户添加该作者的新书,而不是编辑现有的书。有没有一种简单的方法可以使用 inlineformset_factory 来做到这一点?

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

    inlineformset_factory 采用 formset kwarg,默认为 BaseInlineFormSet。 BaseInlineFormSet 是 BaseModelFormSet 的子类,后者定义了一个 get_queryset 方法。如果您创建 BaseInlineFormSet 子类并覆盖 get_queryset 以返回 EmptyQuerySet(),您应该得到您所追求的。在上面的例子中,它看起来像这样:

    from django.db.models.query import EmptyQuerySet
    from django.forms.models import BaseInlineFormSet
    
    class BaseInlineAddOnlyFormSet(BaseInlineFormSet):
        def get_queryset(self):
            return EmptyQuerySet()
    
    author = Author.objects.get(pk=1)
    BookFormSet = inlineformset_factory(Author, Book, formset=BaseInlineAddOnlyFormSet)
    formset = BookFormSet(request.POST, instance=author)
    

    【讨论】:

    • The docs 似乎说设置查询集的首选方法是在调用 super 后覆盖 __init__。但这对我不起作用。您的方法确实如此,就像在调用 super 的 __init__ 之前设置 kwarg queryset 一样。谢谢。
    【解决方案2】:

    基于 Jeremy Lewis,如果你不想继承 BaseInlineFormSet,你可以给你的 BookFormSet 一个空的查询集参数。

    查看伪(未经测试的)Django 1.6 代码示例:

    BookFormSet = inlineformset_factory(parent=Author, model=Book)
    if request.method == "POST":
        formset = BookFormSet(request.POST, request.FILES, instance=author)
        if formset.is_valid():
            formset.save()
    else:
        queryset = Book.objects.none() # does not allow to edit books
        formset = BookFormSet(instance=project, initial=initial, queryset=queryset)
    return render(request, "add_book.html", { "formset": formset, })
    

    【讨论】:

    • inlineformset_factory 现在需要明确指定“字段”参数。只是一个更新。
    • 这就是我的解决方案!谢谢。注意:您需要一个带有过滤器的查询集,Book.objects.all()[0] 之类的东西将不起作用。但这会:Book.objects.filter(pk=1)
    【解决方案3】:

    其实答案在documentation中给出。只是不要给 FormSet 提供任何实例。来自文档:

    >>> from django.forms.models import inlineformset_factory
    >>> BookFormSet = inlineformset_factory(Author, Book)
    >>> author = Author.objects.get(name=u'Mike Royko')
    >>> formset = BookFormSet() # This will create an empty form with your model fields
    

    然后您可以按如下方式创建视图:

    if request.method == "POST":
        formset = BookFormSet(request.POST, request.FILES)
        if formset.is_valid():
            formset.save()
    else:
        formset = BookFormSet()
    return render_to_response("add_book.html", {
        "formset": formset,
    

    希望对你有帮助。

    【讨论】:

    • 这对我不起作用;它仍然使用所有Books 填充表单集。 django 1.4.
    猜你喜欢
    • 2015-06-27
    • 2012-06-19
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    • 2017-02-19
    相关资源
    最近更新 更多