2

我正在尝试将 amodelformset_factory用于一堆模型,这些模型在从 db 中检索到它们后已被处理/过滤。这基本上意味着这些模型已经可以按照我想要的方式用于modelformset_factory. 我想知道是否有办法向工厂传递模型列表(不通过queryset参数访问数据库)?

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

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

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

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

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

4

1 回答 1

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))

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

于 2014-01-06T03:57:31.777 回答