Jaz*_*ell 13 html django admin input filter
我想在Django(admin.py)中过滤数据,并在HTML输入文本框中写入文本.我需要按城市过滤公司,所有城市的列表都太长.我想用一个文本输入替换过滤器中所有城市的列表.我在http://djangosnippets.org/snippets/2429/找到了类似的东西,但有两个问题:
models.py的重要部分看起来像这样
class Company(models.Model):
title = models.CharField(max_length=150,blank=False)
city = models.CharField(max_length=50,blank=True)
Run Code Online (Sandbox Code Playgroud)
来自admin.py的东西
class CatalogAdmin(admin.ModelAdmin):
form = CatalogForm
list_display = ('title','city')
list_filter = ['city',]
Run Code Online (Sandbox Code Playgroud)
所以再次,我需要:1.而不是列表od城市在Django过滤器中显示一个文本输入2.在该文本输入中输入城市neme后,按城市过滤数据(过滤请求可以通过一些提交按钮或通过javascript发送)
感谢yoy所有帖子.
r_b*_*ack 17
如果有人仍然需要这个.它在模板中很小,但是在没有js的情况下实现.
filters.py:
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
}, )
Run Code Online (Sandbox Code Playgroud)
templates/admin/textinput_filter.html:
{% 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 %}
Run Code Online (Sandbox Code Playgroud)
然后根据你的模型admin.py:
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,]
Run Code Online (Sandbox Code Playgroud)
准备使用过滤器看起来像这样.

我正在运行 Django 1.10、1.11 和r_black的解决方案并不完全适合,因为 Django 抱怨过滤器字段必须继承自“FieldListFilter”。
因此,对过滤器进行简单更改以从 FieldListFilter 继承即可解决 Django 抱怨问题,并且不必同时为每个字段指定一个新类。
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
}, )
Run Code Online (Sandbox Code Playgroud)
templates/admin/textinput_filter.html(未更改):
{% 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 %}
Run Code Online (Sandbox Code Playgroud)
用法:
class MyAdmin(admin.ModelAdmin):
list_display = [your fields]
list_filter = [('field 1', SingleTextInputFilter), ('field 2', SingleTextInputFilter), further fields]
Run Code Online (Sandbox Code Playgroud)
虽然这实际上不是您的问题,但这听起来像是Django-Selectables的完美解决方案,您只需几行即可添加 AJAX 支持的 CharField 表单,该表单将从城市列表中选择其条目。查看上面链接中列出的示例。
| 归档时间: |
|
| 查看次数: |
5147 次 |
| 最近记录: |