Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.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
Django管理员默认筛选器_Django_Django Admin - Fatal编程技术网

Django管理员默认筛选器

Django管理员默认筛选器,django,django-admin,Django,Django Admin,我知道我已经做到了这一点,但我不记得怎么做了,也找不到任何关于这一点的文档 默认情况下,如何在管理中的对象列表视图上应用筛选器 我有一个应用程序,其中列出报价,这些报价有一个状态(例如:接受,拒绝,暂停…) 我希望过滤器默认设置为status='accepted',即..您可以覆盖查询集 class QuoteAdmin(admin.ModelAdmin): def get_queryset(self, request): return super(QuoteAdmin,

我知道我已经做到了这一点,但我不记得怎么做了,也找不到任何关于这一点的文档

默认情况下,如何在管理中的对象列表视图上应用筛选器

我有一个应用程序,其中列出报价,这些报价有一个状态(例如:接受,拒绝,暂停…)


我希望过滤器默认设置为status='accepted',即..

您可以覆盖查询集

class QuoteAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        return super(QuoteAdmin,self).get_queryset(request).filter(status="accepted")
但是,通过覆盖queryset,您将永远无法查看状态为“已接受”的报价

或者,您可以链接到以下URL,将过滤器添加到GET参数

/admin/myapp/quote/?status=accepted

最后,这就是我想要的:

def changelist_view(self, request, extra_context=None):
    if not request.GET.has_key('status__exact'):
        q = request.GET.copy()
        q['status__exact'] = '1'
        request.GET = q
        request.META['QUERY_STRING'] = request.GET.urlencode()
    return super(SoumissionAdmin,self).changelist_view(request, extra_context=extra_context)
另一种方式是,在admin类中使用queryset方法不起作用。事实上,它确实会过滤结果,但会破坏过滤功能


我发现的解决方案也不是完美的,用它来选择“全部/过滤器。就我而言,这并不引人注目,而且已经足够好了。

我想我已经找到了一种不限制用户的方法。只需查看referer即可确定用户是否刚刚到达此页面。如果是这样,请根据该筛选器将它们重定向到所需的默认url

def changelist_view(self, request, extra_context=None):
    try:
        test = request.META['HTTP_REFERER'].split(request.META['PATH_INFO'])
        if test and test[-1] and not test[-1].startswith('?') and not request.GET.has_key('status__exact'):
            return HttpResponseRedirect("/admin/app/model/?status__exact=1")
    except: pass # In case there is no referer
    return super(MyModelAdmin,self).changelist_view(request, extra_context=extra_context)

更具可重用性的方法:

class DefaultFilterMixIn(admin.ModelAdmin):
    def changelist_view(self, request, *args, **kwargs):
        from django.http import HttpResponseRedirect
        if self.default_filters:
            try:
                test = request.META['HTTP_REFERER'].split(request.META['PATH_INFO'])
                if test and test[-1] and not test[-1].startswith('?'):
                    url = reverse('admin:%s_%s_changelist' % (self.opts.app_label, self.opts.module_name))
                    filters = []
                    for filter in self.default_filters:
                        key = filter.split('=')[0]
                        if not request.GET.has_key(key):
                            filters.append(filter)
                    if filters:                        
                        return HttpResponseRedirect("%s?%s" % (url, "&".join(filters)))
            except: pass
        return super(DefaultFilterMixIn, self).changelist_view(request, *args, **kwargs)            
然后只需在ModelAdmin上定义默认的_过滤器:

class YourModelAdmin(DefaultFilterMixIn):
    ....
    default_filters = ('snapshot__exact=0',)

这对我很有效,避免了h3提到的“所有”问题

class MyAdmin(admin.ModelAdmin):
  def changelist_view(self, request, extra_context=None):
    referer = request.META.get('HTTP_REFERER', '')
    showall = request.META['PATH_INFO'] in referer and not request.GET.has_key('timeframe')
    if not showall and not request.GET.has_key('param_name_here'):
        q = request.GET.copy()
        q['param_name_here'] = 'default_value_here'
        request.GET = q
        request.META['QUERY_STRING'] = request.GET.urlencode()
    return super(SerializableAdmin,self).changelist_view(request, extra_context=extra_context)

我用“全部”支持解决了这个问题

在models.py中:

STATUSES_CHOICE = (
    ('0', 'Active'),
    ('1', 'Deactive'),
    ('2', 'Suspended'),
)

class Client(models.Model):
    ...
    status = models.IntegerField(verbose_name=_('Status'),
                                 default=0,
                                 db_index=True)
在admin.py中:

class StatusAdminFilter(SimpleListFilter):
    title = _('Status')
    parameter_name = 'status'
    all_param_value = 'all'

    def lookups(self, request, model_admin):
        return STATUSES_CHOICE

    def queryset(self, request, queryset):
        status = self.value()
        try:
            return (queryset if status == self.all_param_value else
                    queryset.filter(status=int(status)))
        except ValueError:
            raise Http404

    def choices(self, cl):
        yield {'selected': self.value() == self.all_param_value,
               'query_string': cl.get_query_string(
                   {self.parameter_name: self.all_param_value}, 
                   [self.parameter_name]),
               'display': _('All')}
        for lookup, title in self.lookup_choices:
            yield {'selected': self.value() == lookup,
                   'query_string': cl.get_query_string(
                       {self.parameter_name: lookup}, []),
                   'display': title}


class ClientAdmin(admin.ModelAdmin):
    list_filter = (StatusAdminFilter,)

    def changelist_view(self, request, extra_context=None):
        if not request.GET.has_key('status'):
            q = request.GET.copy()
            q['status'] = '0'  # default value for status
            request.GET = q
            request.META['QUERY_STRING'] = request.GET.urlencode()
        return super(ClientAdmin, self).changelist_view(
            request, extra_context=extra_context)

短而干净的溶液。单击“更改列表”视图时,使用“全部”选项效果很好

    def changelist_view(self, request, extra_context=None):
        if not request.META['QUERY_STRING'] and \
            not request.META.get('HTTP_REFERER', '').startswith(request.build_absolute_uri()):
            return HttpResponseRedirect(request.path + "?status__exact=1")
        return super(YourModelAdmin,self).changelist_view(request, extra_context=extra_context)

下面是我对glic3rinu代码的更新(请参见此处的注释),它适用于Python 3.4和Django 1.9.7:

class DefaultFilterMixIn(admin.ModelAdmin):
    def changelist_view(self, request, *args, **kwargs):
        from django.http import HttpResponseRedirect
        if self.default_filters:
            #try:
                test = request.META['HTTP_REFERER'].split(request.META['PATH_INFO'])
                if test and test[-1] and not test[-1].startswith('?'):
                    url = reverse('admin:{}_{}_changelist'.format(self.opts.app_label, self.opts.model_name))
                    filters = []
                    for filter in self.default_filters:
                        key = filter.split('=')[0]
                        if not key in request.GET:
                            filters.append(filter)
                    if filters:                     
                        return HttpResponseRedirect("{}?{}".format(url, "&".join(filters)))
            #except: pass
        return super(DefaultFilterMixIn, self).changelist_view(request, *args, **kwargs)            

下面是我在admin中设置默认过滤器的尝试(仅使用Django 1.11测试):


诀窍是检查
self.value()是否为None
以获得默认行为

这是一种硬编码的黑客行为,但这个答案是有效的。我将“/admin/app/model/”替换为request.path,并在发送http响应重定向之前将我的等价物“.status\uuu exact=1”连接到它,以记录这个问题对我来说可能是重复的(这可能会有所不同,因为我使用的是django Grapelli)这只适用于
snapshot=0
而不是
snapshot\uuuu-exact=0
的情况,而且,无论出于何种原因,过滤器不再工作,这是因为javascript被破坏(控制台说:“Uncaught-TypeError:Object[Object-Object]没有方法‘actions’),这也可能是因为grappelli。对不起,这句话太离谱了,哈哈。django==1.3.4和grappelli==2.3.9对我来说效果很好。mixin的主要道具。感谢您提供这段代码,但它不适用于Python3和Django 1.9.7。只是沉默异常并不是一个好主意,所以我把它注释掉了。然后我发现self.opts.module\u名称应该改为self.opts.model\u名称,而“
request.GET.has\u key(key)
”:已经被“
key in request.GET
”:(更新的代码太长,无法在这里被接受)
self.opts.module\u名称
必须替换为
self.opts.model\u名称
,根据Django>=1.8。发布说明:Model._meta.module_name被重命名为Model_name。谢天谢地。我找不到删除“全部”的方法。其他人都说你只是把它忘在了“查找”功能中。事实上,您需要在“选择”函数中省略它http_REFERER并不总是存在(或相关),显然也不会请求_URI(我不知道如何,但我没有它)。。。我看不出一个安全的方法来知道什么时候发生了?否则,将在URL中显示。
class ZeroCountListFilter(admin.SimpleListFilter):
    title = _('include zero count')
    parameter_name = 'count'

    def choices(self, changelist):
        yield {
            'selected': self.value() is None or self.value() == 0,
            'query_string': changelist.get_query_string({}, [self.parameter_name]),
            'display': _('No'),
        }
        yield {
            'selected': self.value() == '1',
            'query_string': changelist.get_query_string({self.parameter_name: '1'}, []),
            'display': _("Yes"),
        }

    def lookups(self, request, model_admin):
        return (
            ('0', _('No')),
            ('1', _('Yes')),
        )

    def queryset(self, request, queryset):
        if self.value() is None or self.value() == '0':
            return queryset.exclude(count=0)
        else:
            return queryset