django admin 中的 ModelChoiceField 给出 'Select a valid choice. That choice is not one of the available choices.' 错误

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

嘿!

我想要在我的 django 管理区域中有一个字段,用户可以在其中 select 从数据库中给定的选项。 例如,获取国家列表并选择一个。但我总是会得到 ' Select 一个有效的选择。该选择不是可用的选择之一。尝试保存新实例时出错。

#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"
                    ]
                }
            )
        ]

我确实在管理下拉菜单中得到了正确的选择,但是当我 select 一个并保存时发生错误。

有没有人知道如何解决这个问题(在管理员中)发现没有管理员部分只有类似的问题,没有解决方案对我有用。

非常感谢您的帮助! :)

编辑:

我在我的管理区域中解决了这个问题,但现在无法在我的 forms/views 中过滤 PlaceSection。 需要的字段在那里,但是在 'search' 之后,TypeError 'PlaceSection' object is not iterable 发生了。它似乎是一个 NoneType 并且是空的,但我不明白我做错了什么。

如有任何进一步的帮助,我们将不胜感激! :)

# 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

ModelChoiceField 接受一个 queryset 参数。你的代码缺少那个。

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

应该如下:

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

而且可能不是 values(),而是 .all()

查看文档:https://docs.djangoproject.com/en/3.2/ref/forms/fields/#django.forms.ModelChoiceField

@moddayjob 帮了我大忙!

我的问题的完整解决方案是:

# models.py 

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

    def code_str(self):
        return self.code

    def __str__(self):
        return f"{self.code}, {self.description_german}"

class Institution(models.Model):
   place_sections = models.ManyToManyField(
        PlaceSection,
    ) 

   def serialize(self):
       return {"place_sections": ", ".join([place.code for place in self.place_sections.all()])}

# admin.py

@admin.register(NaceSection)
class PlaceSectionAdmin(admin.ModelAdmin):
    search_fields = [
        "code",
        "place_sections",
    ]


class InstitutionForm(forms.ModelForm):
        model = Institution 
        fields = [
            "place_sections"
        ]


@admin.register(Institution)
class InstitutionAdmin(admin.ModelAdmin):
    form = InstitutionForm
    save_on_top = True

    fieldsets = ["place_sections"]
    autocomplete_fields = ["place_sections"]
# query.py
def filter_query(form):
    query = Institution.objects.all()
        if form.cleaned_data["place_sections"]:
        place_sections_query = (
            Institution.objects.filter(place_sections__in=form.cleaned_data["place_sections"])
            )
        query = query.intersection(place_sections_query)
# forms.py

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