58๐
Thanks to gpilotino for giving me the push into the right direction for implementing this.
I noticed the questionโs code is using a datetime to figure out when its live . So I used the DateFieldFilterSpec and subclassed it.
from django.db import models
from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec,DateFieldFilterSpec
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext as _
from datetime import datetime
class IsLiveFilterSpec(DateFieldFilterSpec):
"""
Adds filtering by future and previous values in the admin
filter sidebar. Set the is_live_filter filter in the model field attribute
'is_live_filter'. my_model_field.is_live_filter = True
"""
def __init__(self, f, request, params, model, model_admin):
super(IsLiveFilterSpec, self).__init__(f, request, params, model,
model_admin)
today = datetime.now()
self.links = (
(_('Any'), {}),
(_('Yes'), {'%s__lte' % self.field.name: str(today),
}),
(_('No'), {'%s__gte' % self.field.name: str(today),
}),
)
def title(self):
return "Is Live"
# registering the filter
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'is_live_filter', False),
IsLiveFilterSpec))
To use you can put the above code into a filters.py, and import it in the model you want to add the filter to
23๐
you have to write a custom FilterSpec (not documentend anywhere).
Look here for an example:
- [Django]-How to use if/else condition on Django Templates?
- [Django]-Django CSRF Cookie Not Set
- [Django]-Passing variable urlname to url tag in django template
9๐
In current django development version there is the support for custom filters: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter
- [Django]-Matching query does not exist Error in Django
- [Django]-Django + Ajax
- [Django]-How to use refresh token to obtain new access token on django-oauth-toolkit?
3๐
You canโt, unfortunately. Currently non-field items can not be used as list_filter entries.
Note that your admin class wouldnโt have worked even if it was a field, as a single-item tuple needs a comma: ('is_live',)
- [Django]-Django: How to check if the user left all fields blank (or to initial values)?
- [Django]-Is there a way to undo a migration on Django and uncheck it from the list of showmigrations?
- [Django]-Django: How can I protect against concurrent modification of database entries
3๐
Just a sidenote: You can use the deafult ticks on Django admin more easily like this:
def is_live(self):
if self.when_to_publish is not None:
if ( self.when_to_publish < datetime.now() ):
return True
else:
return False
is_live.boolean = True
- [Django]-Creating email templates with Django
- [Django]-Django REST Framework: how to substitute null with empty string?
- [Django]-How do I include related model fields using Django Rest Framework?
3๐
Not an optimal way (CPU-wise) but simple and will work, so I do it this way (for my small database). My Django version is 1.6.
In admin.py:
class IsLiveFilter(admin.SimpleListFilter):
title = 'Live'
parameter_name = 'islive'
def lookups(self, request, model_admin):
return (
('1', 'islive'),
)
def queryset(self, request, queryset):
if self.value():
array = []
for element in queryset:
if element.is_live.__call__() == True:
q_array.append(element.id)
return queryset.filter(pk__in=q_array)
โฆ
class NewsItemAdmin(admin.ModelAdmin):
form = NewsItemAdminForm
list_display = ('headline', 'id', 'is_live')
list_filter = (IsLiveFilter)
Key idea here is to access custom fields in a QuerySet via __call__() function.
- [Django]-Feedback on using Google App Engine?
- [Django]-Django Rest Framework โ Could not resolve URL for hyperlinked relationship using view name "user-detail"
- [Django]-Django โ iterate number in for loop of a template
2๐
The user supplies goods to some countries postage free. I wanted to filter those countries:
All โ all countries, Yes โ postage free, No โ charged postage.
The main answer for this question did not work for me (Django 1.3) I think because there was no field_path
parameter provided in the __init__
method. Also it subclassed DateFieldFilterSpec
. The postage
field is a FloatField
from django.contrib.admin.filterspecs import FilterSpec
class IsFreePostage(FilterSpec):
def __init__(self, f, request, params, model, model_admin, field_path=None):
super(IsFreePostage, self).__init__(f, request, params, model,
model_admin, field_path)
self.removes = {
'Yes': ['postage__gt'],
'No': ['postage__exact'],
'All': ['postage__exact', 'postage__gt'] }
self.links = (
('All', {}),
('Yes', {'postage__exact': 0}),
('No', {'postage__gt': 0}))
if request.GET.has_key('postage__exact'):
self.ttl = 'Yes'
elif request.GET.has_key('postage__gt'):
self.ttl = 'No'
else:
self.ttl = 'All'
def choices(self, cl):
for title, param_dict in self.links:
yield {'selected': title == self.ttl,
'query_string': cl.get_query_string(param_dict,
self.removes[title]),
'display': title}
def title(self):
return 'Free Postage'
FilterSpec.filter_specs.insert(0,
(lambda f: getattr(f, 'free_postage', False), IsFreePostage))
In self.links we supply dicts. used to construct HTTP query strings like ?postage__exact=0
for each of the possible filters. Filters I think are cumulative so if there was a previous request for โNoโ and now we have a request for โYesโ we have to remove the
โNoโ query. self.removes
specifies what needs to be removed for each query. The choices
method constructs the query strings, says which filter has been selected and sets the displayed name of the filter.
- [Django]-FileUploadParser doesn't get the file name
- [Django]-How to use "AND" in a Django filter?
- [Django]-Django REST framework post array of objects
1๐
Here is the answer and implemented the custom filter as simple as possible this might help
- [Django]-How to paginate Django with other get variables?
- [Django]-Separation of business logic and data access in django
- [Django]-Django custom field validator vs. clean