Make組ブログ

Python、Webアプリや製品・サービス開発についてhirokikyが書きます。

FormSet を空の状態で提供する (オブジェクト作成用のビューで使える)

>>> HogeFormSet = modelformset_factory(Hoge)
>>> hoge_formset = HogeFormSet()

とすると、FormSet(ModelFormSet) が DB に保存されている既存のオブジェクトに束縛されて提供される。
この挙動はオブジェクトの新規作成をするビューで使うには好ましくない。
まっさらな状態の FormSet が欲しい。

環境

Django==1.4.1

解法

>>> hoge_formset = HogeFormSet(queryset=Hoge.objects.none())

参考

BaseModelFormSet(django.forms.models.BaseModelFormSet) のソースコードをみると
queryset が None の場合に Manager の get_query_set メソッドを呼んでいる。

   def get_queryset(self):
        if not hasattr(self, '_queryset'):
            if self.queryset is not None:
                qs = self.queryset
            else:
                qs = self.model._default_manager.get_query_set()

https://github.com/django/django/blob/master/django/forms/models.py#L457

Manager の get_query_set メソッドをみてみると、 DB 内の対象 Model を全部返している。

    def get_query_set(self):
        """Returns a new QuerySet object. Subclasses can override this method
        to easily customize the behavior of the Manager.
        """
        return QuerySet(self.model, using=self._db)

https://github.com/django/django/blob/master/django/db/models/manager.py#L118

Hoge.objects.all() でお馴染みの all メソッドも get_query_set メソッドを呼んでいるよう。

    def all(self):
        return self.get_query_set()

https://github.com/django/django/blob/master/django/db/models/manager.py#L127

まとめ

>>> HogeFormSet(Hoge)
>>> # is
>>> HogeFormSet(Hoge, queryset=Hoge.objects.all())