django-viewsdjango-formsdjango-admindjango-errorsmodelchoicefield

ModelChoiceField in django admin gives 'Select a valid choice. That choice is not one of the available choices.' error


Hej!

I want a field in my django admin area where the user can select from given choices in the database. For example get a list of countries and choose one. But I will always get the ' Select a valid choice. That choice is not one of the available choices.' error when you try to save the new instance.

#models.py

class PlaceSection(models.Model):
    code = models.CharField(max_length=1)

        def code_str(self):
        return self.code

# admin.py

class InstiForm(forms.ModelForm):
    place_sections = forms.ModelChoiceField(
        PlaceSection.objects.values(),
        widget=Select2Widget,
    )
    

    class Meta:
        model = Something
        fields = [
            "place_section"]


class InstiAdmin(admin.ModelAdmin):
    form = InstiForm
    save_on_top = True
    def save_model(self, request, obj, form, change):
    fieldsets = [
        (
            ("General"),
                {"fields": [
                    "place_sections"
                    ]
                }
            )
        ]

I do get the right choices in the admin dropdown but when I select one and save the error occurs.

Does anyone has an idea how to fix this (in the admin) found only similar problems without the admin part and no solution worked for me.

Help is really appreciated! :)

Edit:

I fixed the issue in my admin-area but now can't filter for PlaceSection in my forms/views. The needed fields are there, but after the 'search' the TypeError 'PlaceSection' object is not iterable occurs. It seems to be a NoneType and empty but I don't understand what I'm doing wrong.

Any further help is appreciated as well! :)

# forms.py

class SearchForm(forms.Form):
    place_sections = forms.ModelMultipleChoiceField(
        queryset=PlaceSection.objects.all(), widget=Select2MultipleWidget, required=False)     

# views.py

def search_institution(request):
    if request.method == "POST":
        form = SearchForm(request.POST)
        if form.is_valid():
            query = filter_query(form)
            context = {"result_data": serialize(query), "form": form, "show_form": False}
            return render(request, "stakeholders/search_form.html", context)
    else:
        form = SearchForm()

    context = {
        "result_data": serialize(Institution.objects.all()),
        "form": form, 
        "show_form": True
    }
    return render(request, "stakeholders/search_form.html", context)

# query.py

def filter_query(form):
    query = Institution.objects.all()
    if form.cleaned_data["place_sections"]:
        place_sections_query = Institution.objects.none()
        for section in form.cleaned_data["place_sections"]:
            place_sections_query = (
                    place_sections_query
                    | Institution.objects.filter(place_sections__in=section)
            )
        query = query.intersection(place_sections_query)
    return query


Solution

  • ModelChoiceField accepts a queryset argument. Your code is missing that.

    place_sections = forms.ModelChoiceField(
            PlaceSection.objects.values(),
            widget=Select2Widget,
        )
    

    should be as follows:

    place_sections = forms.ModelChoiceField(
            queryset=PlaceSection.objects.all(),
            widget=Select2Widget,
        )
    

    And probably not values() but .all()

    Check out the documentation: https://docs.djangoproject.com/en/3.2/ref/forms/fields/#django.forms.ModelChoiceField