Giter Club home page Giter Club logo

Comments (10)

frnhr avatar frnhr commented on June 22, 2024

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.

runekaagaard avatar runekaagaard commented on June 22, 2024

Thanks for that, hopefully I/we can get django-admin-filtrate 1.4 compatible before it hits stable. Cheers!

from django-admin-filtrate.

brunosmartin avatar brunosmartin commented on June 22, 2024

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.

brunosmartin avatar brunosmartin commented on June 22, 2024

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.

runekaagaard avatar runekaagaard commented on June 22, 2024

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.

andybak avatar andybak commented on June 22, 2024

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.

runekaagaard avatar runekaagaard commented on June 22, 2024

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.

runekaagaard avatar runekaagaard commented on June 22, 2024

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.

mvattuone avatar mvattuone commented on June 22, 2024

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.

runekaagaard avatar runekaagaard commented on June 22, 2024

This is fixed think.

from django-admin-filtrate.

Related Issues (6)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.