初始化没有queryset的modelformset_factory

时间:2013-01-11 11:22:41

标签: django django-forms

我正在尝试将modelformset_factory用于从db检索到的已经处理/过滤的一组模型。它基本上意味着模型已经按照modelformset_factory的方式提供。我想知道是否有办法将工厂的模型列表传递给工厂(没有通过queryset参数访问数据库)?

我能想到的一种方法是模拟QuerySet以返回已处理的模型列表,并将其用作queryset argument

另一种方法可能是使用model_to_dict并使用initial参数将模型转换为dicts列表(因为modelformset_factory是formset_factory的子类) - 不太确定{{1}允许我这样做......

然后我必须缓存用于在请求之间创建表单的模型,以便在实际POST数据到达时跳过模型的检索/处理。

有谁知道是否有更好的方法来解决这类问题?

注意:我想使用modelformset_factory因为我想利用formset的自动前缀和表单处理。

1 个答案:

答案 0 :(得分:0)

迟到总比不上......

我也遇到了这个问题。我通过传递model_to_dict作为初始参数来管理它。但要注意,model_to_dict不返回ForeignKey或ManyToMany字段,所以我必须显式传递这些参数(假设MyModelClass有一个ForeignKey到MyRelatedClass):

forms.py中的助手fn:

def MyInlineFormSetFactory(*args,**kwargs):
  _prefix     = kwargs.pop("prefix","formset")
  _request    = kwargs.pop("request",None)
  _initial    = kwargs.pop("initial",[])
  _instance   = kwargs.pop("instance")
  new_kwargs = {
      "can_delete" : False,
      "extra"      : kwargs.pop("extra",0),
      "form"       : MyForm,
      "fk_name"    : "my_related_name"
  }
  new_kwargs.update(kwargs)
  _formset = inlineformset_factory(MyRelatedModelClass,MyModelClass,*args,**new_kwargs)
  if _request and _request.method == "POST":
    # initialize w/ the request in the event of POST
    return _formset(_request.POST,instance=_instance,prefix=_prefix)
  # otherwise initialize w/ the initial kwarg
  return _formset(initial=_initial,instance=_instance,prefix=_prefix)

其他地方的助手:

def get_initial_data(model,update_fields={}):
  dict = model_to_dict(model)
  # here is where I add the fields that model_to_dict ignores
  dict.update(update_fields)
  return dict

在我看来......

my_related_model = MyRelatedModelClass.objects.get(pk=42)
my_models = MyModelClass.objects.filter(some_key="some_value")
my_initial_data = [get_initial_data(my_model,{"my_related_name" : my_related_model}) for my_model in my_models]
my_formset = MyInlineFormSetFactory(instance=my_related_model,request=request,initial=my_initial_data,extra=len(my_initial_data))

我正在使用内联formset工厂,但你明白了。