【问题标题】:ModelChoiceField in django admin gives 'Select a valid choice. That choice is not one of the available choices.' errordjango admin 中的 ModelChoiceField 给出“选择一个有效的选择。那个选择不是可用的选择之一。错误
【发布时间】:2021-09-02 13:41:31
【问题描述】:

嘿嘿!

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

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

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

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

非常感谢您的帮助! :)

编辑:

我在我的管理区域中解决了这个问题,但现在无法在我的表单/视图中过滤 PlaceSection。 需要的字段在那里,但在“搜索”之后,TypeError 'PlaceSection' 对象不可迭代。它似乎是 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

【问题讨论】:

    标签: django-views django-forms django-admin django-errors modelchoicefield


    【解决方案1】:

    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

    【讨论】:

    • 感谢您的回答!它确实以这种方式工作。我尝试 values() 来获取下拉列表中的名称而不是 ID,仍在处理:D
    • 我还创建了一个 ModelAdmin @admin.register(NaceSection) class PlaceSectionAdmin(admin.ModelAdmin): search_fields = [ "place_sections", ],它确实为我提供了一个字段,我可以在其中进行选择,但我无法在其中进行搜索。结束它仍然没有给我国家,而是ID。你知道如何解决这个问题吗?
    • 是的,在 Django 中,选择框的值默认是模型的 PK。要更改它,您应该使用 to_field_name 属性。只要确保这些值始终是唯一的,这就是您的情况。看看文档中的这一部分:docs.djangoproject.com/en/3.2/ref/forms/fields/…
    • 我也修复了这个问题,但现在无法通过我的表单进行过滤。发生 TypeError 'PlaceSection' 对象不可迭代。你知道我做错了什么吗?
    • 可能您在 for 循环中使用 PlaceSection。如果没有看到模板(或者这个循环在哪里),就不能说任何精确的东西,但要考虑的一件事是。请在互联网上搜索该错误。
    【解决方案2】:

    @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)
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-21
      • 2012-01-22
      • 2018-06-11
      • 2021-04-12
      • 2016-04-06
      • 2020-10-30
      • 2018-04-10
      • 2018-08-13
      相关资源
      最近更新 更多