Thaian
Thaian

Reputation: 1245

Django forms - Select a valid choice. That choice is not one of the available choices

In my form I have select box but when after submit i getting error on this field: "Select a valid choice. That choice is not one of the available choices." I'm using exactly code in other form and there everything works fine but not in this form :(

forms.py:

BLANK_CHOICE = (('', '---------'),)

class ClientCreateForm(forms.ModelForm):
    class Meta:
        model = Client
        fields = ('name', 'address', 'zip_code', 'city', 'country', 'forwarding_address',
                  'forwarding_zip_code', 'forwarding_city', 'forwarding_country')

    def __init__(self, *args, **kwargs):
        super(ClientCreateForm, self).__init__(*args, **kwargs)
        self.fields['country'].choices = CountriesShortcut.objects.all().values_list('id', 'name')
        self.fields['forwarding_country'].choices = BLANK_CHOICE + tuple(
            CountriesShortcut.objects.all().values_list('id', 'name'))

Models.py

class CountriesShortcut(models.Model):
    name = models.CharField(max_length=80, unique=True)

    class Meta:
        ordering = ['id']

    def __init__(self):
        self.code


class Client(models.Model):
    id = models.OneToOneField(User, on_delete=models.CASCADE, unique=True, primary_key=True)
    name = models.CharField(max_length=256, unique=True)
    address = models.CharField(max_length=64)
    zip_code = models.CharField(max_length=10, help_text='Zip Code')
    city = models.CharField(max_length=64)
    country = models.ForeignKey(CountriesShortcut, related_name='country', blank=True, null=True)
    forwarding_address = models.CharField(max_length=64, blank=True)
    forwarding_zip_code = models.CharField(max_length=10, blank=True)
    forwarding_city = models.CharField(max_length=64, blank=True)
    forwarding_country = models.ForeignKey(CountriesShortcut, related_name='forwarding_country', blank=True, null=True)

    def __str__(self):
        re = self.name + ' [' + str(self.id) + ']'
        return re

Can you give me some advice?

Traceback showed after changed to queryset:

Environment:

Request Method: GET
Request URL: http://127.0.0.1:8000/panel/client/create/

Django Version: 1.8.8
Python Version: 3.5.1
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'core',
 'client',
 'registration',
 'avatar',
 'filer',
 'mptt',
 'easy_thumbnails',
 'reversion')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware')

Template error:
In template C:\Users\loc\PycharmProjects\CRM\templates\panel\client\form.html, error at line 131
   __init__() takes 1 positional argument but 3 were given

   121 :                             <div class="col-sm-3">
   122 :                                 {{ form_client.city }}
   123 :                                 {% if form_client.errors.city %}
   124 :                                     <p class="help-block">
   125 :                                         {{ form_client.errors.city }}
   126 :                                         {{ form_client.non_field_errors.city }}
   127 :                                     </p>
   128 :                                 {% endif %}
   129 :                             </div>
   130 :                             <div class="col-sm-3">
   131 :                                  {{ form_client.country }} 
   132 :                                 {% if form_client.errors.country %}
   133 :                                     <p class="help-block">
   134 :                                         {{ form_client.errors.country }}
   135 :                                         {{ form_client.non_field_errors.country }}
   136 :                                     </p>
   137 :                                 {% endif %}
   138 :                             </div>
   139 :                         </div>
   140 :                     </div>
   141 :                 </div>

Traceback:
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\core\handlers\base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
  22.                 return view_func(request, *args, **kwargs)
File "C:\Users\loc\PycharmProjects\CRM\core\views.py" in client_create
  111.         return render(request, 'panel/client/form.html', dict)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\shortcuts.py" in render
  67.             template_name, context, request=request, using=using)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\loader.py" in render_to_string
  99.         return template.render(context, request)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\backends\django.py" in render
  74.         return self.template.render(context)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\base.py" in render
  210.                     return self._render(context)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\base.py" in _render
  202.         return self.nodelist.render(context)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\base.py" in render
  905.                 bit = self.render_node(node, context)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\debug.py" in render_node
  79.             return node.render(context)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\loader_tags.py" in render
  135.         return compiled_parent._render(context)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\base.py" in _render
  202.         return self.nodelist.render(context)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\base.py" in render
  905.                 bit = self.render_node(node, context)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\debug.py" in render_node
  79.             return node.render(context)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\loader_tags.py" in render
  65.                 result = block.nodelist.render(context)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\base.py" in render
  905.                 bit = self.render_node(node, context)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\debug.py" in render_node
  79.             return node.render(context)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\template\debug.py" in render
  92.             output = force_text(output)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\utils\encoding.py" in force_text
  90.                     s = six.text_type(s)
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\utils\html.py" in <lambda>
  399.         klass.__str__ = lambda self: mark_safe(klass_str(self))
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\forms\forms.py" in __str__
  537.         return self.as_widget()
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\forms\forms.py" in as_widget
  593.         return force_text(widget.render(name, self.value(), attrs=attrs))
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\forms\widgets.py" in render
  513.         options = self.render_options(choices, [value])
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\forms\widgets.py" in render_options
  539.         for option_value, option_label in chain(self.choices, choices):
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\forms\models.py" in __iter__
  1107.             for obj in queryset:
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\db\models\query.py" in iterator
  255.             obj = model_cls.from_db(db, init_list, row[model_fields_start:model_fields_end])
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\db\models\base.py" in from_db
  489.             new = cls(*values)

Exception Type: TypeError at /panel/client/create/
Exception Value: __init__() takes 1 positional argument but 3 were given

Upvotes: 1

Views: 8094

Answers (1)

Karolis Ryselis
Karolis Ryselis

Reputation: 679

Your fields are foreign keys. By default django sets all available values for fields in forms to all objects of the model. Looking at your code, I think you could just remove ClientCreateForm __init__ completely.

If you still want to set your custom choices, you should not set choices attribute. You should use queryset:

class ClientCreateForm(forms.ModelForm):
# your meta goes here

    def __init__(self, *args, **kwargs):
        super(ClientCreateForm, self).__init__(*args, **kwargs)
        self.fields['country'].queryset = CountriesShortcut.objects.all()
        self.fields['forwarding_country'].queryset = CountriesShortcut.objects.all()

Your fields are marked as null=True, so empty dash will be added automatically.

choices should be used if you have non-relationship field, for example, CharField with choices attribute set.

Upvotes: 4

Related Questions