Comments (10)
I changed Date filter so that it works with Django 1.4 rc1. Maybe it can be of help in rewriting Filtrate for new version.
__init__.py
is now empty
filters.py:
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from django.forms.widgets import Media, MEDIA_TYPES, Input, HiddenInput
from django import forms as f
from django.contrib.admin.filters import SimpleListFilter
from filtrate import settings
class FiltrateFilter(SimpleListFilter):
def __init__(self, request, params, model, model_admin, *args, **kwargs):
self.request = request
super(FiltrateFilter, self).__init__(request, params, model, model_admin, *args, **kwargs)
self._add_media(model_admin)
def title(self):
"""Triggers the alternate rendering in "filter.html"."""
return '__filtrate__'
def has_output(self):
return True
def lookups(self, request, model_admin):
return None
def queryset(self, request, queryset):
"""
Returns the filtered queryset.
"""
return None
def choices(self, cl):
"""As only title and choices is passed to "filter.html" template, we
sets title to "__filtrate__" and passes real title and content from
here.
"""
return [{
'title': self.get_title(),
'content': self.get_content(),
}]
# Must be overridden.
def get_title(self):
"""The title of the filter. Must include "After" in the beginning."""
raise NotImplementedError()
def get_content(self):
"""The content part of the filter in html."""
raise NotImplementedError()
class Media():
js = ( 'filtrate/js/filtrate.js',)
css = { 'all': ('filtrate/css/filtrate.css',) }
def _add_media(self, model_admin):
def _get_media(obj):
return Media(media=getattr(obj, 'Media', None))
media = _get_media(model_admin) + _get_media(FiltrateFilter)\
+ _get_media(self)
for name in MEDIA_TYPES:
setattr(model_admin.Media, name, getattr(media, "_" + name))
def _form_duplicate_getparams(self, omitted_fields):
"""Replicates the get parameters as hidden form fields."""
s = '<input type="hidden" name="%s" value="%s"/>'
_omitted_fields = tuple(omitted_fields) + ('e',)
return "".join([s % (k,v) for k,v in self.request.GET.iteritems()
if k not in _omitted_fields])
class DateRangeFilter(FiltrateFilter):
class Media():
js = (
'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/i18n/jquery-ui-i18n.min.js',
'filtrate/js/daterangefilter.js',
)
css = { 'all': ('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/flick/jquery-ui.css',) }
def _get_form(self, parameter_name):
"""
Returns form with from and to fields. The '__alt' fields are alternative
fields with the correct non localized dateform needed for Django,
handled by jsTree.
"""
from_name = self.parameter_name + '__gte'
to_name = self.parameter_name + '__lte'
display_widget = Input(attrs={'class': 'filtrate_date'})
hidden_widget = HiddenInput(attrs={'class': 'filtrate_date_hidden'})
def add_fields(fields, name, label):
fields[name + '__alt'] = f.CharField(label=label,
widget=display_widget, required=False)
fields[name] = f.CharField(widget=hidden_widget, required=False)
def add_data(data, name, request):
date = request.GET.get(name)
if date:
data[name + '__alt'] = date
class DateRangeForm(f.Form):
def __init__(self, *args, **kwargs):
super(DateRangeForm, self).__init__(*args, **kwargs)
add_fields(self.fields, from_name, _('From'))
add_fields(self.fields, to_name, _('To'))
data = {}
add_data(data, from_name, self.request)
add_data(data, to_name, self.request)
return DateRangeForm(data=data)
def get_title(self):
"""The title of the filter. Must include "After" in the beginning."""
# "After"... say what?
return u'After title'
def get_content(self):
form = self._get_form(self.parameter_name)
return mark_safe(u"""
<script>
var filtrate = filtrate || {};
filtrate.datepicker_region = '%(datepicker_region)s';
filtrate.datepicker_date_format = '%(datepicker_date_format)s';
</script>
<form class="filtrate_daterange_form" method="get">
%(form)s
<input type="submit" value="%(submit)s" />
<input type="submit" value="%(clear)s" class="cancel" />
%(get_params)s
</form>
""" % ({
'form': form.as_p(),
'submit': _('Apply filter'),
'clear': _('Clear'),
'datepicker_region': settings.FILTRATE['datepicker_region'],
'datepicker_date_format': settings.FILTRATE['datepicker_date_format'],
'get_params': self._form_duplicate_getparams(form.fields.keys()),
}))
It's definitely not a pretty solution (note the queryset method!), but surprisingly it works.
Anyhow, hope it helps.
There is no TreeFilter, I don't use it so I didn't get around to tackle it...
from django-admin-filtrate.
Thanks for that, hopefully I/we can get django-admin-filtrate 1.4 compatible before it hits stable. Cheers!
from django-admin-filtrate.
I This worked in django 1.4:
class DateRangeFilter2(DateFieldListFilter):
template = 'filter.html'
def __init__(self, field, request, params, model, model_admin, field_path):
super(DateRangeFilter2, self).__init__(
field, request, params, model, model_admin, field_path)
self._add_media(model_admin)
self.request = request
def choices(self, cl):
for title, param_dict in self.links:
yield {
'selected': self.date_params == param_dict,
'query_string': cl.get_query_string(
param_dict, [self.field_generic]),
'display': title,
}
yield {
'selected': self.date_params == param_dict,
'content': self.get_content(),
'display': u'Data variavel',
}
def _form_duplicate_getparams(self, omitted_fields):
"""Replicates the get parameters as hidden form fields."""
s = '<input type="hidden" name="%s" value="%s"/>'
_omitted_fields = tuple(omitted_fields) + ('e',)
return "".join([s % (k,v) for k,v in self.request.GET.iteritems()
if k not in _omitted_fields])
def _get_form(self):
"""
Returns form with from and to fields. The '__alt' fields are alternative
fields with the correct non localized dateform needed for Django,
handled by jsTree.
"""
from_name = self.field_path + '__gte'
to_name = self.field_path + '__lte'
display_widget = Input(attrs={'class': 'filtrate_date'})
hidden_widget = HiddenInput(attrs={'class': 'filtrate_date_hidden'})
def add_fields(fields, name, label):
fields[name + '__alt'] = f.CharField(label=label,
widget=display_widget, required=False)
fields[name] = f.CharField(widget=hidden_widget, required=False)
def add_data(data, name, request):
date = request.GET.get(name)
if date:
data[name + '__alt'] = date
class DateRangeForm(f.Form):
def __init__(self, *args, **kwargs):
super(DateRangeForm, self).__init__(*args, **kwargs)
add_fields(self.fields, from_name, _('From'))
add_fields(self.fields, to_name, _('To'))
data = {}
add_data(data, from_name, self.request)
add_data(data, to_name, self.request)
return DateRangeForm(data=data)
def get_content(self):
form = self._get_form()
return mark_safe(u"""
<script>
var filtrate = filtrate || {};
filtrate.datepicker_region = '%(datepicker_region)s';
filtrate.datepicker_date_format = '%(datepicker_date_format)s';
</script>
<form class="filtrate_daterange_form" method="get">
%(form)s
<input type="submit" value="%(submit)s" />
<input type="submit" value="%(clear)s" class="cancel" />
%(get_params)s
</form>
""" % ({
'form': form.as_p(),
'submit': _('Apply filter'),
'clear': _('Clear'),
'datepicker_region': settings.FILTRATE['datepicker_region'],
'datepicker_date_format': settings.FILTRATE['datepicker_date_format'],
'get_params': self._form_duplicate_getparams(form.fields.keys()),
}))
class Media():
js = (
'filtrate/js/filtrate.js',
'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/i18n/jquery-ui-i18n.min.js',
'filtrate/js/daterangefilter.js',
)
css = { 'all': ('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/flick/jquery-ui.css', 'filtrate/css/filtrate.css') }
def _add_media(self, model_admin):
def _get_media(obj):
return Media(media=getattr(obj, 'Media', None))
media = _get_media(model_admin) + _get_media(DateRangeFilter2)\
+ _get_media(self)
for name in MEDIA_TYPES:
setattr(model_admin.Media, name, getattr(media, "_" + name))
from django-admin-filtrate.
I changed the tempalte too...
{% comment %}
This is a modification of the standard filter.html template that allows for
more flexible filters.
If a filter returns its title as "__filtrate__" the more flexible rendering
is activated and the `choices()` method of the filter must return a dict
wrapped in a list with the keys `title` and `content` instead.
{% endcomment %}
{% load i18n %}
{% blocktrans with title as filter_title %} By {{ filter_title }} {% endblocktrans %}
-
{% for choice in choices %}
{% if not choice.content %}
<li{% if choice.selected %} class="selected"{% endif %}>
<a href="{{ choice.query_string|iriencode }}">{{ choice.display }}</a></li>
{% else %}
<li{% if choice.selected %} class="selected"{% endif %}>
<div class="filtrate">
<div class="content">
{{choice.content}}
</div>
</div>
</li>
{% endif %}
{% endfor %}
from django-admin-filtrate.
Just writing here to say that I've started working on bringing the entire app up to Django 1.4. Expect more news soon :)
from django-admin-filtrate.
I'd recommend jumping straight to 1.6 (if not 1.7) if you're going to the trouble. 1.7 is a bit more fiddly but targeting 1.6 instead of 1.4 shouldn't be a significant increase in complexity.
from django-admin-filtrate.
I got 1.4 (and probably later versions too) working in the v1.4 branch. Both TreeFilter and DateRangeFilter works:
class CompanyDepartmentFilter(TreeFilter):
parameter_name = 'client__department__id__in'
title = 'By department'
def get_tree(self):
from myapp.models import Department
qs = Department.objects.all()
return groupby(qs, lambda obj: getattr(obj, 'customer'))
class CaseAddedDateRangeFilter(DateRangeFilter):
parameter_name = 'start_date'
title = 'By start date'
So if anyone feels adventurous, then go play with it :)
from django-admin-filtrate.
The v1.4 branch now works (for me) in both Django 1.4 and 1.7. https://github.com/runekaagaard/django-admin-filtrate/tree/v1.4
from django-admin-filtrate.
This sort of works, but I had to do a few things to get it to work using 1.7.1, rather than having immediate out of the box support. It still saved me a ton of time though, so thank you! I just wanted to pass off some notes for you, hopefully useful...
- I had to override the is_active function such that it was only looking for the filtrate class. I think maybe it is because I'm using a bootstrap admin package, but I did not have #changelist-filter in my DOM.
- In your test for the 1.4 version, you have a list filter that contains a tuple of the parameter name and the class name. It should just be the class name.
- If I click on the datepicker, it closes the dropdown behind it, which is sort of poor UX. Not sure if that's something at the datepicker level, but I may look into it some more if I can find some time.
from django-admin-filtrate.
This is fixed think.
from django-admin-filtrate.
Related Issues (6)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-admin-filtrate.