Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何限制Django admin中的选项数_Python_Django - Fatal编程技术网

Python 如何限制Django admin中的选项数

Python 如何限制Django admin中的选项数,python,django,Python,Django,假设我有两个模型,Group和Person,其中Group是Person的外键字段。在“管理员”页面中,组表示为“管理员”人员的下拉/选择字段。现在,我希望选择的数量限制在,比如说,五个,并且它们应该根据它们的名称排序 目前,我有以下代码: class PersonAdmin(admin.ModelAdmin): form = PersonAdminForm ... def formfield_for_foreignkey(self, db_field, request=

假设我有两个模型,
Group
Person
,其中
Group
Person
的外键字段。在“管理员”页面中,组表示为“管理员”人员的下拉/选择字段。现在,我希望选择的数量限制在,比如说,五个,并且它们应该根据它们的
名称
排序

目前,我有以下代码:

class PersonAdmin(admin.ModelAdmin):
    form = PersonAdminForm
    ...
    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        if db_field.name == 'group':
            kwargs['queryset'] = Group.objects.all().order_by('name')[:5]

        return super(PersonAdmin, self).formfield_for_foreignkey(
            db_field, request, **kwargs)

class PersonAdminForm(forms.ModelForm):
    class Meta:
        model = Person
问题是,当我试图保存对象时,会出现以下错误:
AssertionError:一旦获取一个切片,就无法过滤查询。

我搜索了那个错误,找到了很多这样的线索,但似乎没有一个能帮我解决这个问题

以下是完整的堆栈跟踪:

Traceback (most recent call last):
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 111, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/contrib/admin/options.py", line 583, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/utils/decorators.py", line 105, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/views/decorators/cache.py", line 52, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/contrib/admin/sites.py", line 206, in inner
    return view(request, *args, **kwargs)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/contrib/admin/options.py", line 1453, in add_view
    return self.changeform_view(request, None, form_url, extra_context)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/utils/decorators.py", line 29, in _wrapper
    return bound_func(*args, **kwargs)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/utils/decorators.py", line 105, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/utils/decorators.py", line 25, in bound_func
    return func.__get__(self, type(self))(*args2, **kwargs2)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/db/transaction.py", line 394, in inner
    return func(*args, **kwargs)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/contrib/admin/options.py", line 1396, in changeform_view
    if form.is_valid():
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/forms/forms.py", line 162, in is_valid
    return self.is_bound and not bool(self.errors)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/forms/forms.py", line 154, in errors
    self.full_clean()
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/forms/forms.py", line 353, in full_clean
    self._clean_fields()
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/forms/forms.py", line 368, in _clean_fields
    value = field.clean(value)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/forms/fields.py", line 150, in clean
    value = self.to_python(value)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/forms/models.py", line 1185, in to_python
    value = self.queryset.get(**{key: value})
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/db/models/query.py", line 345, in get
    clone = self.filter(*args, **kwargs)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/db/models/query.py", line 691, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/home/man/.virtualenvs/foo/local/lib/python2.7/site-packages/django/db/models/query.py", line 703, in _filter_or_exclude
    "Cannot filter a query once a slice has been taken."
AssertionError: Cannot filter a query once a slice has been taken.

您可以在init方法中修改queryset,找到前五个组
id
,然后通过
查找中的
\u对
pk
进行筛选

class PersonAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(PersonAdminForm, self).__init__(*args, **kwargs)
        group_ids = Group.objects.all().order_by('name').values_list('pk', flat=True)[:5]
        self.fields['group'].queryset = Group.objects.filter(pk__in=group_ids).order_by('name')

    group = forms.ModelChoiceField(queryset=None, empty_label=None)

    class Meta:
        model = Person
        fields = '__all__'

为了避免过滤切片查询集时出错,您可能需要先获取前五个组,然后在
查找中使用
\uu创建第二个查询集。这很难,但我认为它会奏效

first_five = list(Group.objects.all().order_by('name')[:5].values('pk', flat=True))
queryset = Group.objects.filter(id__in=first_five).order_by('name')[:5]

如果您已经有一个自定义模型表单,那么我认为该代码最干净的地方应该是表单的
\uuuu init\uuuu
方法,而不是覆盖
formfield\u for\u foreignkey

如果您有一个自定义表单类(例如
form=PersonalAdminform
),这是否也适用于您的自定义表单类,我想你会直接找到
group
字段作为
form.group.queryset
而不是
form.base\u字段['group']
dict对于查询中的错误,很抱歉,你指定的字段实际上就是我的。
form.group
不起作用。我将尝试
base\u字段
方法发布您的PersonalAdminform类。您还可以重写表单类的init方法。请显示完整的回溯。@Alasdair说明已更新。