0

I have a ModelForm with some fake fields that I process later when save the model.

class MyForm(forms.ModelForm):
    field1= forms.IntegerField(min_value=0)
    field2= forms.ChoiceField(choices=SIDES_CHOICES, required=True)
    field3= forms.CharField(max_length=140, required=False)

What I need is to show or to hide some of them depending on whether we are adding a new instance or changing an existing one.

All I read is about hide real fields that are defined in the model, but it's not my case. With 'fake' i mean fields that are not in the model or database, only defined in the form.

I have tried this in the __init__ override of the ModelForm:

def __init__(self, *args, **kwargs):
    super(MyForm, self).__init__(*args, **kwargs)
    if not self.instance.pk:
        del self.fields['field1']

But I get this error:

Key 'field1' not found in 'MyForm'

Entire error traceback:

Template error:
In template C:\Python34\lib\site-packages\django_suit-0.2.18-py3.4.egg\suit\templates\admin\change_form.html, error at line 19
   Key 'field1' not found in 'MyForm'   9 :   {{ media }}
   10 : 
   11 : {% endblock %}
   12 : 
   13 : 
   14 : {% block extrajs %}
   15 :   {{ block.super }}
   16 : 
   17 :   {% if 'CONFIRM_UNSAVED_CHANGES'|suit_conf %}
   18 :     <!-- Warn on leaving unsaved form -->
   19 :     <script src="{% static  'suit/js/suit-form- confirm.js' %}"></script>
   20 :     <script type="text/javascript">
   21 :       confirmExitIfModified('{% firstof opts.model_name opts.module_name %}_form', '{% trans 'You have unsaved changes' %}.');
   22 :     </script>
   23 :   {% endif %}
   24 : 
   25 :   {% if adminform.model_admin.suit_form_tabs %}
   26 :     <script type="text/javascript">
   27 :     (function ($) {
   28 :       $(function () {
   29 :         $('#suit_form_tabs').suit_form_tabs();


Traceback:

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\forms\forms.py" in __getitem__
  141.             field = self.fields[name]

During handling of the above exception ('field1'), another exception occurred:

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\core\handlers\base.py" in get_response
  174.                     response = self.process_exception_by_middleware(e, request)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\core\handlers\base.py" in get_response
  172.                     response = response.render()

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\response.py" in render
  160.             self.content = self.rendered_content

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\response.py" in rendered_content
  137.         content = template.render(context, self._request)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\backends\django.py" in render
  95.             return self.template.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render
  206.                     return self._render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in _render
  197.         return self.nodelist.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render
  992.                 bit = node.render_annotated(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render_annotated
  959.             return self.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\loader_tags.py" in render
  173.         return compiled_parent._render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in _render
  197.         return self.nodelist.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render
  992.                 bit = node.render_annotated(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render_annotated
  959.             return self.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\loader_tags.py" in render
  173.         return compiled_parent._render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in _render
  197.         return self.nodelist.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render
  992.                 bit = node.render_annotated(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render_annotated
  959.             return self.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\loader_tags.py" in render
  69.                 result = block.nodelist.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render
  992.                 bit = node.render_annotated(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render_annotated
  959.             return self.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\loader_tags.py" in render
  69.                 result = block.nodelist.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render
  992.                 bit = node.render_annotated(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render_annotated
  959.             return self.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render
  1043.             output = self.filter_expression.resolve(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in resolve
  709.                 obj = self.var.resolve(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in resolve
  850.             value = self._resolve_lookup(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in _resolve_lookup
  913.                             current = current()

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\loader_tags.py" in super
  83.             return mark_safe(self.render(self.context))

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\loader_tags.py" in render
  69.                 result = block.nodelist.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render
  992.                 bit = node.render_annotated(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render_annotated
  959.             return self.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\loader_tags.py" in render
  69.                 result = block.nodelist.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render
  992.                 bit = node.render_annotated(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render_annotated
  959.             return self.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\loader_tags.py" in render
  69.                 result = block.nodelist.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render
  992.                 bit = node.render_annotated(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render_annotated
  959.             return self.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\defaulttags.py" in render
  220.                     nodelist.append(node.render_annotated(context))

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render_annotated
  959.             return self.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\loader_tags.py" in render
  209.                 return template.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render
  208.                 return self._render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in _render
  197.         return self.nodelist.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render
  992.                 bit = node.render_annotated(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render_annotated
  959.             return self.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\defaulttags.py" in render
  220.                     nodelist.append(node.render_annotated(context))

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render_annotated
  959.             return self.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\defaulttags.py" in render
  584.             return self.nodelist.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render
  992.                 bit = node.render_annotated(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in render_annotated
  959.             return self.render(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\defaulttags.py" in render
  319.                     match = condition.eval(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\defaulttags.py" in eval
  951.         return self.value.resolve(context, ignore_failures=True)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in resolve
  709.                 obj = self.var.resolve(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in resolve
  850.             value = self._resolve_lookup(context)

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\template\base.py" in _resolve_lookup
  913.                             current = current()

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\contrib\admin\helpers.py" in errors
  117.             for f in self.fields if f not in self.readonly_fields).strip('\n')

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\contrib\admin\helpers.py" in <genexpr>
  117.             for f in self.fields if f not in self.readonly_fields).strip('\n')

File "C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\forms\forms.py" in __getitem__
  144.                 "Key %r not found in '%s'" % (name, self.__class__.__name__))
toscanelli
  • 1,202
  • 2
  • 17
  • 40
  • 3
    You'll need to give more information. What is a "fake field" and how does it differ from a real field? How are you defining those fields in the first place? – Daniel Roseman Jun 09 '16 at 11:37
  • Before or after calling `super()`? – C14L Jun 09 '16 at 12:16
  • Sorry for my short question. I have already edited. Fake field is a field that is only in the form, not in the model or database table. What I tried is after super(). – toscanelli Jun 09 '16 at 12:50
  • Add the extra fields to the `fields` list in the `Meta` class. – evergreen Jun 09 '16 at 13:15
  • @evergreen They are already in it, but I delete what I don't want to be shown in the `__init__` method, and it seems django doesn't like this... – toscanelli Jun 09 '16 at 13:23
  • If you comment out the line `del self.fields['field1']`, do all of the fields appear in the form? – evergreen Jun 09 '16 at 14:13
  • @evergreen yes, all of them – toscanelli Jun 09 '16 at 14:23
  • If you add `for f in self.fields:` and `print(f + '\n')` does it list the "fake" fields? – evergreen Jun 09 '16 at 14:45
  • Yes, they are there. If I delete on of the fake fields it is deleted without problems from the dict, but after this, django server crashes – toscanelli Jun 09 '16 at 14:53
  • Try going back to your original code and try `del self.fields['field2']` Does that work? If the fields are in the dict, then `del` shouldn't give you a key error. – evergreen Jun 09 '16 at 15:24
  • `del`doesn't give me any error. the error comes later when load the form in the browser – toscanelli Jun 09 '16 at 15:35
  • Okay. I think I finally understand. Somewhere in your ModelForm code you are probably referencing `field1` after you have already removed it from the form. – evergreen Jun 09 '16 at 15:40

1 Answers1

0

You are removing field1 from the form in __init__ if the form is used for a new instance of the model. The key error means that at least one place in your ModelForm code is referencing field1 after you have already removed it (for a new instance). If the error traceback doesn't point you to the line that's generating the error, just search your code for occurrences of field1 and make sure that you're testing for a new instance before you execute each of those sections of code.

Edit Since the form is being used as an AdminForm, Comment out the lines in the ModelForm where you delete field1 and add the following to your ModelAdmin, based on an answer to Remove fields from ModelForm:

def get_form(self, request, obj=None, **kwargs):
    form = super().get_form(request, obj=obj, **kwargs)
    if not obj:
        self.exclude = ['field1',]
    return form
Community
  • 1
  • 1
evergreen
  • 856
  • 6
  • 7
  • The error comes from this line: `C:\Python34\lib\site-packages\django-1.9.6-py3.4.egg\django\forms\forms.py in __getitem__, line 144` I am not referencing this field (consciously) in any other part of my code. – toscanelli Jun 10 '16 at 07:40
  • Can you please post the entire error traceback? You can just edit your original question. – evergreen Jun 10 '16 at 09:29
  • Thanks for the suggestion. Done! – toscanelli Jun 10 '16 at 10:21
  • The error is apparently from the admin. Are there any references to `field1` in your ModelAdmin? – evergreen Jun 10 '16 at 10:49
  • No one. These fields must not be shown in the changelist, and I don't have any other list of fields but list_display. In list_display I just have fields from the model. – toscanelli Jun 10 '16 at 11:05