Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 4608736
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 22, 20262026-05-22T00:53:15+00:00 2026-05-22T00:53:15+00:00

does someone know how to filter in admin based on comparison on model fields

  • 0

does someone know how to filter in admin based on comparison on model fields – F() expressions?

Let’s assume we have following model:

class Transport(models.Model):
    start_area = models.ForeignKey(Area, related_name='starting_transports')
    finish_area = models.ForeignKey(Area, related_name='finishing_transports')

Now, what I would like to do is to make admin filter which allows for filtering of in-area and trans-area objects, where in-area are those, whose start_area and finish_area are the same and trans-area are the others.

I have tried to accomplish this by creating custom FilterSpec but there are two problems:

  • FilterSpec is bound to only one field.
  • FilterSpec doesn’t support F() expressions and exclude.

The second problem might be solved by defining custom ChangeList class, but I see no way to solve the first one.

I also tried to “emulate” the filter straight in the ModelAdmin instance by overloading queryset method and sending extra context to the changelist template where the filter itself would be hard-coded and printed by hand. Unfortunately, there seems to be problem, that Django takes out my GET parameters (used in filter link) as they are unknown to the ModelAdmin instance and instead, it puts only ?e=1 which is supposed to signal some error.

Thanks anyone in advance.

EDIT: It seems that functionality, which would allow for this is planned for next Django release, see http://code.djangoproject.com/ticket/5833. Still, does someone have a clue how to accomplish that in Django 1.2?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-22T00:53:16+00:00Added an answer on May 22, 2026 at 12:53 am

    The solution involves adding your FilterSpec and as you said implementing your own ChangeList. As the filter name is validated, you must name your filter with a model field name. Below you will see a hack allowing to use the default filter for the same field.

    You add your FilterSpec before the standard FilterSpecs.

    Below is a working implementation running on Django 1.3

    from django.contrib.admin.views.main import *
    from django.contrib import admin
    from django.db.models.fields import Field
    from django.contrib.admin.filterspecs import FilterSpec
    from django.db.models import F
    from models import Transport, Area
    from django.contrib.admin.util import get_fields_from_path
    from django.utils.translation import ugettext as _
    
    
    # Our filter spec
    class InAreaFilterSpec(FilterSpec):
    
        def __init__(self, f, request, params, model, model_admin, field_path=None):
            super(InAreaFilterSpec, self).__init__(
                f, request, params, model, model_admin, field_path=field_path)
            self.lookup_val = request.GET.get('in_area', None)
    
        def title(self):
            return 'Area'
    
        def choices(self, cl):
            del self.field._in_area
            yield {'selected': self.lookup_val is None,
                   'query_string': cl.get_query_string({}, ['in_area']),
                   'display': _('All')}
            for pk_val, val in (('1', 'In Area'), ('0', 'Trans Area')):
                yield {'selected': self.lookup_val == pk_val,
                       'query_string': cl.get_query_string({'in_area' : pk_val}),
                       'display': val}
    
        def filter(self, params, qs):
            if 'in_area' in params:
                if params['in_area'] == '1':
                    qs = qs.filter(start_area=F('finish_area'))
                else:
                    qs = qs.exclude(start_area=F('finish_area'))
                del params['in_area']
            return qs
    
    def in_area_test(field):
        # doing this so standard filters can be added with the same name
        if field.name == 'start_area' and not hasattr(field, '_in_area'):
            field._in_area = True
            return True    
        return False
    
    # we add our special filter before standard ones
    FilterSpec.filter_specs.insert(0, (in_area_test, InAreaFilterSpec))
    
    
    # Defining my own change list for transport
    class TransportChangeList(ChangeList):
    
        # Here we are doing our own initialization so the filters
        # are initialized when we request the data
        def __init__(self, request, model, list_display, list_display_links, list_filter, date_hierarchy, search_fields, list_select_related, list_per_page, list_editable, model_admin):
            #super(TransportChangeList, self).__init__(request, model, list_display, list_display_links, list_filter, date_hierarchy, search_fields, list_select_related, list_per_page, list_editable, model_admin)
            self.model = model
            self.opts = model._meta
            self.lookup_opts = self.opts
            self.root_query_set = model_admin.queryset(request)
            self.list_display = list_display
            self.list_display_links = list_display_links
            self.list_filter = list_filter
            self.date_hierarchy = date_hierarchy
            self.search_fields = search_fields
            self.list_select_related = list_select_related
            self.list_per_page = list_per_page
            self.model_admin = model_admin
    
            # Get search parameters from the query string.
            try:
                self.page_num = int(request.GET.get(PAGE_VAR, 0))
            except ValueError:
                self.page_num = 0
            self.show_all = ALL_VAR in request.GET
            self.is_popup = IS_POPUP_VAR in request.GET
            self.to_field = request.GET.get(TO_FIELD_VAR)
            self.params = dict(request.GET.items())
            if PAGE_VAR in self.params:
                del self.params[PAGE_VAR]
            if TO_FIELD_VAR in self.params:
                del self.params[TO_FIELD_VAR]
            if ERROR_FLAG in self.params:
                del self.params[ERROR_FLAG]
    
            if self.is_popup:
                self.list_editable = ()
            else:
                self.list_editable = list_editable
            self.order_field, self.order_type = self.get_ordering()
            self.query = request.GET.get(SEARCH_VAR, '')
            self.filter_specs, self.has_filters = self.get_filters(request)
            self.query_set = self.get_query_set()
            self.get_results(request)
            self.title = (self.is_popup and ugettext('Select %s') % force_unicode(self.opts.verbose_name) or ugettext('Select %s to change') % force_unicode(self.opts.verbose_name))
            self.pk_attname = self.lookup_opts.pk.attname
    
    
        # To be able to do our own filter,
        # we need to override this
        def get_query_set(self):
    
            qs = self.root_query_set
            params = self.params.copy()
    
            # now we pass the parameters and the query set 
            # to each filter spec that may change it
            # The filter MUST delete a parameter that it uses
            if self.has_filters: 
                for filter_spec in self.filter_specs:
                    if hasattr(filter_spec, 'filter'):
                        qs = filter_spec.filter(params, qs)
    
            # Now we call the parent get_query_set()
            # method to apply subsequent filters
            sav_qs = self.root_query_set
            sav_params = self.params
    
            self.root_query_set = qs
            self.params = params
    
            qs = super(TransportChangeList, self).get_query_set()
    
            self.root_query_set = sav_qs
            self.params = sav_params
    
            return qs
    
    
    class TransportAdmin(admin.ModelAdmin):
        list_filter = ('start_area','start_area')
    
        def get_changelist(self, request, **kwargs):
            """
            Overriden from ModelAdmin
            """
            return TransportChangeList
    
    
    admin.site.register(Transport, TransportAdmin)
    admin.site.register(Area)
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Can someone please explain what the & does in the following: class TEST {
Does someone know a free web-based test case management software? I looked around in
Does someone know of a comparison between ZK and Vaadin ? I'm especially interested
Does someone know if it is possible to modify the JVM settings at runtime
Does anyone know of any documentation by MS or someone else that lays out
Does someone have any tips/advice on database design for a web application? The kind
I just started to read about this new technology... Does someone have some knowledge
Does someone know of a good ruby testing library for generating English (or maybe
Does someone know how can I return the @@Identity when using T-Sql? Something like
Does someone know a way to remove requests from an ASINetworkQueue in a persistent

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.