django - How to create dynamic methods with python? -
for project need dynamically create custom (class) methods.
i found out not easy in python:
class userfilter(django_filters.filterset): ''' filter used in api ''' # legacy below, has added dynamically #is_field_type1 = methodfilter(action='filter_field_type1') #def filter_field_type1(self, queryset, value): # return queryset.filter(related_field__field_type1=value) class meta: model = get_user_model() fields = []
but giving me errors (and headaches...). possible?
i try make code between #legacy dynamic
one option found create class dynamically
def create_filter_dict(): new_dict = {} field in list_of_fields: def func(queryset, value): _filter = {'stableuser__'+field:value} return queryset.filter(**_filter) new_dict.update({'filter_'+field: func}) new_dict.update({'is_'+field: methodfilter(action='filter_'+field)}) return new_dict meta_model_dict = {'model': get_user_model(), 'fields':[]} meta_type = type('meta',(), meta_model_dict) filter_dict = create_filter_dict() filter_dict['meta'] = meta_type userfilter = type('userfilter', (django_filters.filterset,), filter_dict)
however, giving me
typeerror @ /api/v2/users/ func() takes 2 positional arguments 3 given
does know how solve dilemma?
exception value: 'userfilter' object has no attribute 'is_bound'
you getting error because class methods generating, not bound class. bound them class, need use setattr()
try on console:
class myclass(object): pass @classmethod def unbound(cls): print "now i'm bound ", cls print unbound setattr(myclass, "bound", unbound) print myclass.bound print myclass.bound()
traceback: userfilter = type('foo', (django_filters.filterset, ), create_filter_dict().update({'meta':type('meta',(), {'model': get_user_model(), 'fields':[]} )})) typeerror: type() argument 3 must dict, not none
now, failing because dict.update() doesn't return same instance, returns none. can fixed
class_dict = create_filter_dict() class_dict.update({'meta':type('meta',(), {'model': get_user_model(), 'fields':[]})} userfilter = type('foo', (django_filters.filterset, ), class_dict))
however, how messy code looks. recommend try clearer code write if requires write few lines. in long run, code easier maintain , team.
meta_model_dict = {'model': get_user_model(), 'fields':[]} meta_type = type('meta',(), meta_model_dict) filter_dict = create_filter_dict() filter_dict['meta'] = meta_type userfilter = type('foo', (django_filters.filterset,), filter_dict)
this code might not perfect more readable original line of code posted:
userfilter = type('foo', (django_filters.filterset, ), create_filter_dict().update({'meta':type('meta',(), {'model': get_user_model(), 'fields':[]})}))
and removes complication on kinda difficult concept grasp.
you might want learn metaclasses. maybe can overwrite new method of class. can recommend 1 or 2 posts that.
another option maybe not adding filters correctly or in way django doesn't expect? explain why no errors none of functions gets called.
Comments
Post a Comment