首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django admin.py过滤器中的HTML输入文本框

Django admin.py过滤器中的HTML输入文本框
EN

Stack Overflow用户
提问于 2011-07-03 13:37:04
回答 4查看 9.3K关注 0票数 15

我想在Django (admin.py)中使用中的文本写来过滤数据。我需要按所在城市对公司进行筛选,所有城市的名单都太长了。我想用一个文本输入替换所有城市的过滤列表。我在这里发现了一些类似的东西,http://djangosnippets.org/snippets/2429/,但是有两个问题:

  1. 作者没有发布models.py,所以很难根据我的需要修改代码(+没有注释)
  2. 有已使用的类UserFieldFilterSpec( RelatedFilterSpec ):但是我需要使用AllValuesFilterSpec而不是RelatedFilterSpec(更多在RelatedFilterSpec文件中),因为城镇列表与comapny属于同一类(按城镇类别列出,它们应该是按外键引用公司(ManyToMany关系),但出于某些原因,必须这样做)

models.py的重要部分如下所示

代码语言:javascript
复制
class Company(models.Model):
    title = models.CharField(max_length=150,blank=False)
    city = models.CharField(max_length=50,blank=True)

来自admin.py的东西

代码语言:javascript
复制
class CatalogAdmin(admin.ModelAdmin):
    form = CatalogForm
    list_display = ('title','city') 
    list_filter = ['city',]

因此,我再次需要: 1.不再在Django filter 2中显示一个城市列表输入的文本。在输入文本输入的城市名称后,按城市过滤数据(可以通过提交按钮或通过javascript发送过滤请求)

感谢你所有的帖子。

EN

回答 4

Stack Overflow用户

发布于 2013-12-14 22:27:41

以防还有人需要这个。它在模板上有点麻烦,但在没有js的情况下实现。

filters.py

代码语言:javascript
复制
from django.contrib.admin import ListFilter
from django.core.exceptions import ImproperlyConfigured


class SingleTextInputFilter(ListFilter):
    """
    renders filter form with text input and submit button
    """
    parameter_name = None
    template = "admin/textinput_filter.html"

    def __init__(self, request, params, model, model_admin):
        super(SingleTextInputFilter, self).__init__(
            request, params, model, model_admin)
        if self.parameter_name is None:
            raise ImproperlyConfigured(
                "The list filter '%s' does not specify "
                "a 'parameter_name'." % self.__class__.__name__)

        if self.parameter_name in params:
            value = params.pop(self.parameter_name)
            self.used_parameters[self.parameter_name] = value

    def value(self):
        """
        Returns the value (in string format) provided in the request's
        query string for this filter, if any. If the value wasn't provided then
        returns None.
        """
        return self.used_parameters.get(self.parameter_name, None)

    def has_output(self):
        return True

    def expected_parameters(self):
        """
        Returns the list of parameter names that are expected from the
        request's query string and that will be used by this filter.
        """
        return [self.parameter_name]

    def choices(self, cl):
        all_choice = {
            'selected': self.value() is None,
            'query_string': cl.get_query_string({}, [self.parameter_name]),
            'display': _('All'),
        }
        return ({
            'get_query': cl.params,
            'current_value': self.value(),
            'all_choice': all_choice,
            'parameter_name': self.parameter_name
        }, )

templates/admin/textinput_filter.html

代码语言:javascript
复制
{% load i18n %}
<h3>{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}</h3>

{#i for item, to be short in names#}
{% with choices.0 as i %}
<ul>
    <li>
        <form method="get">
            <input type="search" name="{{ i.parameter_name }}" value="{{ i.current_value|default_if_none:"" }}"/>

            {#create hidden inputs to preserve values from other filters and search field#}
            {% for k, v in i.get_query.items %}
                {% if not k == i.parameter_name %}
                    <input type="hidden" name="{{ k }}" value="{{ v }}">
                {% endif %}
            {% endfor %}
            <input type="submit" value="{% trans 'apply' %}">
        </form>
    </li>

    {#show "All" link to reset current filter#}
    <li{% if i.all_choice.selected %} class="selected"{% endif %}>
        <a href="{{ i.all_choice.query_string|iriencode }}">
            {{ i.all_choice.display }}
        </a>
    </li>
</ul>
{% endwith %}

然后根据您在admin.py中的模型

代码语言:javascript
复制
class CatalogCityFilter(SingleTextInputFilter):
    title = 'City'
    parameter_name = 'city'

    def queryset(self, request, queryset):
        if self.value():
            return queryset.filter(city__iexact=self.value())

class CatalogAdmin(admin.ModelAdmin):
    form = CatalogForm
    list_display = ('title','city') 
    list_filter = [CatalogCityFilter,]

准备使用过滤器的样子是这样的。

票数 20
EN

Stack Overflow用户

发布于 2017-05-13 02:13:19

我正在运行Django 1.10、1.11和黑色解决方案不完全合适,因为Django抱怨过滤器字段必须从'FieldListFilter‘继承。

因此,对过滤器从FieldListFilter继承的简单更改处理了Django的抱怨,而不必同时为每个字段指定一个新的类。

代码语言:javascript
复制
class SingleTextInputFilter(admin.FieldListFilter):
    """
    renders filter form with text input and submit button
    """

    parameter_name = None
    template = "admin/textinput_filter.html"

    def __init__(self, field, request, params, model, model_admin, field_path):
        super().__init__(field, request, params, model, model_admin, field_path)
        if self.parameter_name is None:
            self.parameter_name = self.field.name

        if self.parameter_name in params:
            value = params.pop(self.parameter_name)
            self.used_parameters[self.parameter_name] = value

    def queryset(self, request, queryset):
        if self.value():
            return queryset.filter(imei__icontains=self.value())

    def value(self):
        """
        Returns the value (in string format) provided in the request's
        query string for this filter, if any. If the value wasn't provided then
        returns None.
        """
        return self.used_parameters.get(self.parameter_name, None)

    def has_output(self):
        return True

    def expected_parameters(self):
        """
        Returns the list of parameter names that are expected from the
        request's query string and that will be used by this filter.
        """
        return [self.parameter_name]

    def choices(self, cl):
        all_choice = {
            'selected': self.value() is None,
            'query_string': cl.get_query_string({}, [self.parameter_name]),
            'display': _('All'),
        }
        return ({
            'get_query': cl.params,
            'current_value': self.value(),
            'all_choice': all_choice,
            'parameter_name': self.parameter_name
        }, )

模板/admin/textinput_filter.html(未更改):

代码语言:javascript
复制
{% load i18n %}
<h3>{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}</h3>

{#i for item, to be short in names#}
{% with choices.0 as i %}
<ul>
    <li>
        <form method="get">
            <input type="search" name="{{ i.parameter_name }}" value="{{ i.current_value|default_if_none:"" }}"/>

            {#create hidden inputs to preserve values from other filters and search field#}
            {% for k, v in i.get_query.items %}
                {% if not k == i.parameter_name %}
                    <input type="hidden" name="{{ k }}" value="{{ v }}">
                {% endif %}
            {% endfor %}
            <input type="submit" value="{% trans 'apply' %}">
        </form>
    </li>

    {#show "All" link to reset current filter#}
    <li{% if i.all_choice.selected %} class="selected"{% endif %}>
        <a href="{{ i.all_choice.query_string|iriencode }}">
            {{ i.all_choice.display }}
        </a>
    </li>
</ul>
{% endwith %}

用法:

代码语言:javascript
复制
class MyAdmin(admin.ModelAdmin):
    list_display = [your fields]
    list_filter = [('field 1', SingleTextInputFilter), ('field 2', SingleTextInputFilter), further fields]
票数 5
EN

Stack Overflow用户

发布于 2011-07-03 14:18:10

虽然这实际上不是您的问题,但对于Django-选择来说,这似乎是一个完美的解决方案,只需几行就可以添加一个AJAX驱动的CharField表单,从城市列表中选择它的条目。查看上面链接中列出的示例。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6563196

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档