Login

Foreign Key list_filter wthout custom FilterSpec

Author:
haileris23
Posted:
February 4, 2010
Language:
Python
Version:
1.1
Score:
2 (after 2 ratings)

This is some (probably) pretty dodgy code that allows for foreign keys in the admin's list_filter without using a custom FilterSpec. It overrides the django.db.models.options.Options get_field class to handle spanned relationships, i.e. list_filter=('houseroomtown',) as seen in http://code.djangoproject.com/ticket/3400

I have only tested this with a double foreign key relationship('house__room'), and it worked. It hasn't been tested in production, and the troubling part of this code is probably to use of 'deepcopy'. I do add those copies back to the options instance, so there shouldn't be too much runaway copying.

 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
from django.db.models.fields import FieldDoesNotExist
import copy
from django.db.models.fields.related import ForeignKey

def get_field(self, name, many_to_many=True):
	"""
	Returns the requested field by name. Raises FieldDoesNotExist on error.
	"""
	to_search = many_to_many and (self.fields + self.many_to_many) or self.fields
	if hasattr(self, '_copy_fields'):
		to_search += self._copy_fields
	for f in to_search:
		if f.name == name:
			return f
	if not name.startswith('__') and '__' in name:
		f = None 
		model = self 
		path = name.split('__') 
		for field_name in path: 
			f = model._get_field(field_name)
			if isinstance(f, ForeignKey):
				model = f.rel.to._meta
		f = copy.deepcopy(f)
		f.name = name
		if not hasattr(self, "_copy_fields"):
			self._copy_fields = list()
		self._copy_fields.append(f)
		return f
	raise FieldDoesNotExist, '%s has no field named %r' % (self.object_name, name)

setattr(options.Options, '_get_field', options.Options.get_field.im_func)
setattr(options.Options, 'get_field', get_field)

More like this

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

Comments

denilton (on April 21, 2010):

I have problems in the setattr. Where i should put that? In my class Model, doesn´t recognize options. Thanks

#

haileris23 (on June 10, 2010):

I put the setattr call in the admin.py for my app.

#

andybak (on October 1, 2010):

I think he means that you get the error 'name 'options' is not defined'

Is there a missing 'from django.db.models import options'?

#

haileris23 (on January 18, 2011):

Sorry, yes that import should be there so that options will be recognized

#

ronnas (on July 27, 2011):

i don't really understand how to use it. who calls get_field?

#

rudast (on August 21, 2013):

how i can use it? in admin.py how i can use it as field?

#

Please login first before commenting.