Login

regex search in admin forms

Author:
mbee
Posted:
November 24, 2013
Language:
Python
Version:
1.6
Score:
1 (after 1 ratings)

Despite warning coming from django developers, I'm still using admin classes to quickly get into reverse engineering databases.

One feature is missing: searching into fields thanks to a regex.

One dirty solution I found is to overwrite get_search_results. But most of the code comes from django itself.

If anyone has a better idea ;)

Usage:

  1. works since get_search_results is part of ModelAdmin (1.5 if I remember well)
  2. Inherit your Admin class from RegexModelAdmin
  3. enclose by / the field you want to regex with: search_fields = ['/field/', ]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from django.contrib.admin.util import lookup_needs_distinct

class RegexModelAdmin(admin.ModelAdmin):

    # code coming from django 1.6
    def get_search_results(self, request, queryset, search_term):
        """
        Returns a tuple containing a queryset to implement the search,
        and a boolean indicating if the results may contain duplicates.
        """
        # Apply keyword searches.
        def construct_search(field_name):
            if field_name.startswith('^'):
                return "%s__istartswith" % field_name[1:]
            elif field_name.startswith('='):
                return "%s__iexact" % field_name[1:]
            elif field_name.startswith('@'):
                return "%s__search" % field_name[1:]
            elif field_name.startswith('/') and field_name.endswith('/') and len(field_name) > 2:
                return "%s__regex" % field_name[1:-1]
            else:
                return "%s__icontains" % field_name

        use_distinct = False
        if self.search_fields and search_term:
            orm_lookups = [construct_search(str(search_field))
                           for search_field in self.search_fields]
            for bit in search_term.split():
                or_queries = [models.Q(**{orm_lookup: bit})
                              for orm_lookup in orm_lookups]
                queryset = queryset.filter(reduce(operator.or_, or_queries))
            if not use_distinct:
                for search_spec in orm_lookups:
                    if lookup_needs_distinct(self.opts, search_spec):
                        use_distinct = True
                        break

        return queryset, use_distinct

class TokenAdmin(RegexModelAdmin):
    list_display = ('token', 'token_type')
    search_fields = ['/token/',
                     '/token_type/',
                    ]

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 1 week ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 1 week ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 9 months, 4 weeks ago
  5. Help text hyperlinks by sa2812 10 months, 3 weeks ago

Comments

andybak (on November 25, 2013):

Despite warning coming from django developers, I'm still using admin classes to quickly get into reverse engineering databases.

I think you might find the community divided on this point. The sheer number of admin apps and tweaks shows you're not alone in finding this a good approach to take! Nearly all the major Django CMS projects are heavily based on the Django Admin, for instance.

#

Please login first before commenting.