带有queryset

时间:2016-05-18 18:28:28

标签: django django-models django-forms django-views inline-formset

我需要根据视图传递的对象id过滤表单上的foreignkey选项。 我有以下观点:

@login_required()
def QAView(request, equipamento_id):
    form = ActividadeForm()
    equipamento = Equipamento.objects.get(id=equipamento_id)
    testes_list = Teste.objects.filter(equipamento=equipamento_id)  
    form1 = inlineformset_factory(
              Actividade, Resultado, form=ResultadoForm, 
              exclude=('actividade',), extra=len(testes_list))

    context = {'equipamento_id': equipamento_id, 
               'data':datetime.now(), 'equipamento': equipamento, 
               'form': form, 'testes_list': testes_list, 
               'form1': form1}
    template = 'SFM/Equipamento/QA.html'
    return render(request, template, context)

以下是我的表格:

class ActividadeForm(forms.ModelForm):      
    class Meta:
        model = Actividade
        fields = ['tipo']
        exclude = ['conclusoes']


class ResultadoForm(forms.ModelForm):
    frequencia = forms.CharField(max_length=50)
    tolerancia = forms.CharField(max_length=255)
    #def __init__(self, equipamento_id, *args, **kwargs):
        #super (ResultadoForm,self ).__init__(*args,**kwargs)
        #self.fields['teste'].queryset = Teste.objects.filter(equipamento=equipamento_id)
    class Meta:
        model = Resultado
        exclude = ['actividade']

这会将所有睾丸(这是Teste Model的外键)传递给表格。我需要的是查询这个外键以仅获得与视图给出的equipamento_id相关的睾丸。 Teste与Equipamento有很多关系。 如果我这样做:

form1 = inlineformset_factory(Actividade, Resultado, form=ResultadoForm(equipamento_id), exclude=('actividade',), extra=len(testes_list))

并定义在ResultadoForm中注释的 init 方法,我收到以下错误:

Traceback:

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\core\handlers\base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\core\handlers\base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\contrib\auth\decorators.py" in _wrapped_view
  23.                 return view_func(request, *args, **kwargs)

File "C:\Users\i11931\Documents\DjangoProjects\IPO\SFM\views.py" in QAView
  37.       exclude=('actividade',), extra=len(testes_list))

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\forms\models.py" in inlineformset_factory
  1049.     FormSet = modelformset_factory(model, **kwargs)

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\forms\models.py" in modelformset_factory
  847.                              error_messages=error_messages, field_classes=field_classes)

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\forms\models.py" in modelform_factory
  545.     return type(form)(class_name, (form,), form_class_attrs)

File "C:\Users\i11931\Documents\DjangoProjects\IPO\SFM\forms.py" in __init__
  23.       self.fields['teste'].queryset = Teste.objects.filter(equipamento=equipamento_id)

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\db\models\manager.py" in manager_method
  122.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\db\models\query.py" in filter
  790.         return self._filter_or_exclude(False, *args, **kwargs)

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\db\models\query.py" in _filter_or_exclude
  808.             clone.query.add_q(Q(*args, **kwargs))

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\db\models\sql\query.py" in add_q
  1243.         clause, _ = self._add_q(q_object, self.used_aliases)

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\db\models\sql\query.py" in _add_q
  1269.                     allow_joins=allow_joins, split_subq=split_subq,

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\db\models\sql\query.py" in build_filter
  1199.             condition = lookup_class(lhs, value)

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\db\models\lookups.py" in __init__
  19.         self.rhs = self.get_prep_lookup()

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\db\models\fields\related_lookups.py" in get_prep_lookup
  98.                     self.lookup_name, self.rhs)

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\db\models\fields\__init__.py" in get_prep_lookup
  744.             return self.get_prep_value(value)

File "C:\Users\i11931\Programas\Python3.5.1\lib\site-packages\django-1.9-py3.5.egg\django\db\models\fields\__init__.py" in get_prep_value
  976.         return int(value)

Exception Type: ValueError at /SFM/Equipamento/6/QA/
Exception Value: invalid literal for int() with base 10: 'ResultadoForm'

但如果我将form1替换为:

form1 = ResultadoForm(equipamento_id)

我能够过滤与该equipamento_id相关的睾丸,但我不能创建内联关系。为什么是这样?如何将该equipamento_id传递给inlineformset以生成查询集?请帮忙......

1 个答案:

答案 0 :(得分:1)

这是问题

 return type(form)(class_name, (form,), form_class_attrs)

这是您的表单初始化的地方。传递给表单的__init__方法的第一个参数是String形式的类名。但是,您的__init__看起来像这样

def __init__(self, equipamento_id, *args, **kwargs):
    super (ResultadoForm,self ).__init__(*args,**kwargs)
    self.fields['teste'].queryset = Teste.objects.filter(equipamento=equipamento_id)

此处的第一个参数是equipamento_id,并指定了' ResultadoForm'但是您在查询过滤器的下一行中将它用作整数。因此错误。查看modelform_factory的源代码,并不清楚如何通过inlineformset_factory将equipamento_id作为参数实际传递。

你必须尝试像

这样的东西
 equipamento_id = kwargs.pop('equipamento_id')

但我不确定如何通过inlineform_set发送。