在Django中从视图传递变量到表单时出现错误。

huangapple go评论66阅读模式
英文:

Error while passing Variable from View to Form in Django

问题

I try to send a variable form View to Form in Django. I find a solution and it's working but the problem is that I have to call the fonction form = DonneeForm(variable=variable) but it seems to just send me the entire HTML code. So I would like to find a way for the DonneeForm() to behave as DonneeForm which work but doesn't allow me to send a variable.

Thanks

Form.py

class DonneeForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        self.boitier = kwargs.pop("boitier", 1)  # client is the parameter passed from views.py
        super().__init__(*args, **kwargs)
        boitier = get_object_or_404(Boitier, pk=int(self.boitier))
        self.fields['connexion_donnee'].queryset = boitier.donnee

    class Meta:
        model = Donnee
        fields = ['utilise', 'connexion_donnee', 'nom', 'type_donnee', 'valeur_min', 'valeur_max', 'tolerance', 'afficher_valeur', 'inverse']
        labels = {
        }
        widgets = {
            'type_donnee': forms.Select(attrs={"readonly": "True"})
        }

View.py

type_capteur = get_object_or_404(TypeCapteur, pk=pk)
capteur = get_object_or_404(Capteur, pk=article)
type_capteur_donnees = type_capteur.donnee.all().count()
print(DonneeForm(boitier=boitier.pk))
form = DonneeForm(boitier=boitier.pk)
donnee_form_set = formset_factory(form, extra=type_capteur_donnees, max_num=type_capteur_donnees, absolute_max=type_capteur_donnees)
formset_donnee = donnee_form_set
if request.method == 'POST':
    formset = donnee_form_set(request.POST, request.FILES)
    if formset.is valid():
        for form in formset:
            if form.cleaned_data:
                donnee = form.save(commit=False)
                donnee.capteur = capteur
                donnee.save()
            capteur.save()
        return redirect("smart_workshop_app:configuration_capteurs")
else:
    initial = []
    for type_donnee in type_capteur.donnee.all():
        initial.append({'type_donnee': type_donnee, 'nom': type_donnee.nom})
    formset = formset_donnee(initial=initial)
    print(formset_donnee)
context = {"formset": formset, "instance_id": pk, "instance_article": article}
return render(request, 'smart_workshop_app/ajouter_donnees_capteur.html', context)

Error:

<tr>
    <th><label for="id_utilise">Donnée utilisée&#160;:</label></th>
    <td>
      
      <input type="checkbox" name="utilise" id="id_utilise">
      
      
    </td>
  </tr>

  <tr>
    <th><label for="id_connexion_donnee">Connexion donnee&#160;:</label></th>
    <td>
      
      <select name="connexion_donnee" id="id_connexion_donnee">
  <option value="" selected>---------</option>

  <option value="1">Capt_Distance_Dist_0</option>
 
      [...]
    </td>
  </tr>
Internal Server Error: /fr/ajouter_donnees_capteur/4/28
Traceback (most recent call last):
  File "C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
    raise exc_info[1]
  File "C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\django\core\handlers\exception.py", line 38, in inner
    response = await get_response(request)
  File "C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\django\core\handlers\base.py", line 233, in _get_response_async
    response = await wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\asgiref\sync.py", line 435, in __call__
    ret = await asyncio.wait_for(future, timeout=None)
  File "C:\Users\regac\anaconda3\envs\smart_workshop\lib\asyncio\tasks.py", line 408, in wait_for
    return await fut
  File "C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\asgiref\current_thread_executor.py", line 22, in run
    result = self.fn(*self.args, **self.kwargs)
  File "C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
    return func(*args, **kwargs)
  File "C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\django\utils\decorators.py", line 130, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "C:\Users\regac\PycharmProjects\djangoProject\smart_workshop\smart_workshop_app\views.py", line 268, in ajouter_donnees_capteur
    donnee_form_set = formset_factory(form, extra=type_capteur_donnees, max_num=type_capteur_donnees,
  File "C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\django\forms\formsets.py", line 495, in formset_factory
    return type(form.__name__ + 'FormSet', (formset,), attrs)
AttributeError: 'DonneeForm' object has no attribute '__name__'
HTTP GET /fr/ajouter_donnees_capteur/4/28?boitier=2 500 [0.26, 127.0.0.1:51847]
C:\Users\regac\PycharmProjects\djangoProject\smart_workshop\smart_workshop_app\views.py changed, reloading.
英文:

I try to send a variable form View to Form in Django. I find a solution and it's working but the problem is that I have to call the fonction form = DonneeForm(variable=variable) but it seems to just send me the entire HTML code. So I would like to find a way for the DonneeForm() to behave as DonneeForm which work but doesn't allow me to send a variable.

Thanks

Form.py

class DonneeForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        self.boitier = kwargs.pop(&quot;boitier&quot;, 1)  # client is the parameter passed from views.py
        super().__init__(*args, **kwargs)
        boitier = get_object_or_404(Boitier, pk=int(self.boitier))
        self.fields[&#39;connexion_donnee&#39;].queryset = boitier.donnee

    class Meta:
        model = Donnee
        fields = [&#39;utilise&#39;, &#39;connexion_donnee&#39;, &#39;nom&#39;, &#39;type_donnee&#39;, &#39;valeur_min&#39;, &#39;valeur_max&#39;, &#39;tolerance&#39;, &#39;afficher_valeur&#39;, &#39;inverse&#39;]
        labels = {
        }
        widgets = {
            &#39;type_donnee&#39;: forms.Select(attrs={&quot;readonly&quot;: &quot;True&quot;})
        }

View.py

type_capteur = get_object_or_404(TypeCapteur, pk=pk)
    capteur = get_object_or_404(Capteur, pk=article)
    type_capteur_donnees = type_capteur.donnee.all().count()
    print(DonneeForm(boitier=boitier.pk))
    form = DonneeForm(boitier=boitier.pk)
    donnee_form_set = formset_factory(form, extra=type_capteur_donnees, max_num=type_capteur_donnees,
                                      absolute_max=type_capteur_donnees)
    formset_donnee = donnee_form_set
    if request.method == &#39;POST&#39;:
        formset = donnee_form_set(request.POST, request.FILES)
        if formset.is_valid():
            for form in formset:
                if form.cleaned_data:
                    donnee = form.save(commit=False)
                    donnee.capteur = capteur
                    donnee.save()
                capteur.save()
            return redirect(&quot;smart_workshop_app:configuration_capteurs&quot;)
    else:
        initial = []
        for type_donnee in type_capteur.donnee.all():
            initial.append({&#39;type_donnee&#39;: type_donnee, &#39;nom&#39;: type_donnee.nom})
        formset = formset_donnee(initial=initial)
        print(formset_donnee)
    context = {&quot;formset&quot;: formset, &quot;instance_id&quot;: pk, &quot;instance_article&quot;: article}
    return render(request, &#39;smart_workshop_app/ajouter_donnees_capteur.html&#39;, context)

Error:

&lt;tr&gt;
    &lt;th&gt;&lt;label for=&quot;id_utilise&quot;&gt;Donn&#233;e utilis&#233;e&#160;:&lt;/label&gt;&lt;/th&gt;
    &lt;td&gt;
      
      &lt;input type=&quot;checkbox&quot; name=&quot;utilise&quot; id=&quot;id_utilise&quot;&gt;
      
      
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;th&gt;&lt;label for=&quot;id_connexion_donnee&quot;&gt;Connexion donnee&#160;:&lt;/label&gt;&lt;/th&gt;
    &lt;td&gt;
      
      &lt;select name=&quot;connexion_donnee&quot; id=&quot;id_connexion_donnee&quot;&gt;
  &lt;option value=&quot;&quot; selected&gt;---------&lt;/option&gt;

  &lt;option value=&quot;1&quot;&gt;Capt_Distance_Dist_0&lt;/option&gt;
 
      [...]
    &lt;/td&gt;
  &lt;/tr&gt;
Internal Server Error: /fr/ajouter_donnees_capteur/4/28
Traceback (most recent call last):
  File &quot;C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\asgiref\sync.py&quot;, line 472, in thread_handler
    raise exc_info[1]
  File &quot;C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\django\core\handlers\exception.py&quot;, line 38, in inner
    response = await get_response(request)
  File &quot;C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\django\core\handlers\base.py&quot;, line 233, in _get_response_async
    response = await wrapped_callback(request, *callback_args, **callback_kwargs)
  File &quot;C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\asgiref\sync.py&quot;, line 435, in __call__
    ret = await asyncio.wait_for(future, timeout=None)
  File &quot;C:\Users\regac\anaconda3\envs\smart_workshop\lib\asyncio\tasks.py&quot;, line 408, in wait_for
    return await fut
  File &quot;C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\asgiref\current_thread_executor.py&quot;, line 22, in run
    result = self.fn(*self.args, **self.kwargs)
  File &quot;C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\asgiref\sync.py&quot;, line 476, in thread_handler
    return func(*args, **kwargs)
  File &quot;C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\django\contrib\auth\decorators.py&quot;, line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File &quot;C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\django\utils\decorators.py&quot;, line 130, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File &quot;C:\Users\regac\PycharmProjects\djangoProject\smart_workshop\smart_workshop_app\views.py&quot;, line 268, in ajouter_donnees_capteur
    donnee_form_set = formset_factory(form, extra=type_capteur_donnees, max_num=type_capteur_donnees,
  File &quot;C:\Users\regac\anaconda3\envs\smart_workshop\lib\site-packages\django\forms\formsets.py&quot;, line 495, in formset_factory
    return type(form.__name__ + &#39;FormSet&#39;, (formset,), attrs)
AttributeError: &#39;DonneeForm&#39; object has no attribute &#39;__name__&#39;
HTTP GET /fr/ajouter_donnees_capteur/4/28?boitier=2 500 [0.26, 127.0.0.1:51847]
C:\Users\regac\PycharmProjects\djangoProject\smart_workshop\smart_workshop_app\views.py changed, reloading.

答案1

得分: 0

问题在于你需要将表单类传递给 formset_factory,并通过表单集传递自定义的参数(在这种情况下是 boitier.pk)到表单中。

为此,你可以使用表单集的 form_kwargs 参数。在 Django 中文档中有详细说明。

type_capteur = get_object_or_404(TypeCapteur, pk=pk)
capteur = get_object_or_404(Capteur, pk=article)
type_capteur_donnees = type_capteur.donnee.all().count()
form = DonneeForm
donnee_form_set = formset_factory(form, extra=type_capteur_donnees, max_num=type_capteur_donnees, absolute_max=type_capteur_donnees)
formset_donnee = donnee_form_set
if request.method == &#39;POST&#39;:
    # 这里我们传递了 form_kwargs
    formset = donnee_form_set(request.POST, request.FILES, form_kwargs={&#39;boitier&#39;: boitier.pk})
    if formset.is_valid():
        for form in formset:
            if form.cleaned_data:
                donnee = form.save(commit=False)
                donnee.capteur = capteur
                donnee.save()
            capteur.save()
        return redirect(&quot;smart_workshop_app:configuration_capteurs&quot;)
else:
    initial = []
    for type_donnee in type_capteur.donnee.all():
        initial.append({&#39;type_donnee&#39;: type_donnee, &#39;nom&#39;: type_donnee.nom})
    formset = formset_donnee(initial=initial)
    print(formset_donnee)
context = {&quot;formset&quot;: formset, &quot;instance_id&quot;: pk, &quot;instance_article&quot;: article}
return render(request, &#39;smart_workshop_app/ajouter_donnees_capteur.html&#39;, context)
英文:

The issue is that you need to pass the form class to the formset_factory and pass your custom kwargs (in this case the boitier.pk) via the formset to the form.

For that you can use the form_kwargs argument of the formset. Documented here in Django

    type_capteur = get_object_or_404(TypeCapteur, pk=pk)
    capteur = get_object_or_404(Capteur, pk=article)
    type_capteur_donnees = type_capteur.donnee.all().count()
    form = DonneeForm
    donnee_form_set = formset_factory(form, extra=type_capteur_donnees, max_num=type_capteur_donnees,
                                      absolute_max=type_capteur_donnees)
    formset_donnee = donnee_form_set
    if request.method == &#39;POST&#39;:
        # HERE WE PASS THE FORM_KWARGS
        formset = donnee_form_set(request.POST, request.FILES, form_kwargs={&#39;boitier&#39;: boitier.pk})
        if formset.is_valid():
            for form in formset:
                if form.cleaned_data:
                    donnee = form.save(commit=False)
                    donnee.capteur = capteur
                    donnee.save()
                capteur.save()
            return redirect(&quot;smart_workshop_app:configuration_capteurs&quot;)
    else:
        initial = []
        for type_donnee in type_capteur.donnee.all():
            initial.append({&#39;type_donnee&#39;: type_donnee, &#39;nom&#39;: type_donnee.nom})
        formset = formset_donnee(initial=initial)
        print(formset_donnee)
    context = {&quot;formset&quot;: formset, &quot;instance_id&quot;: pk, &quot;instance_article&quot;: article}
    return render(request, &#39;smart_workshop_app/ajouter_donnees_capteur.html&#39;, context)

huangapple
  • 本文由 发表于 2023年2月24日 17:14:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75554648.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定