Hello everybody, This snippet is working fine, i used this instead of adding custom arguments when overloading each of my ModelForm's constructore to keep the same __init__() signature. http://www.djangosnippets.org/snippets/1272/
Currently refactoring, it makes sense to use a factory in my case. I tryed to copy the pattern of forms.model.modelform_factory, but now it seems that my __init__() method is not overloading ModelForm anymore Recall the code of forms.model.modelform_factory: /trunk/django/forms/models.py 326 def modelform_factory(model, form=ModelForm, fields=None, exclude=None, 327 formfield_callback=lambda f: f.formfield()): 328 # HACK: we should be able to construct a ModelForm without creating 329 # and passing in a temporary inner class 330 class Meta: 331 pass 332 setattr(Meta, 'model', model) 333 setattr(Meta, 'fields', fields) 334 setattr(Meta, 'exclude', exclude) 335 class_name = model.__name__ + 'Form' 336 return ModelFormMetaclass(class_name, (form,), {'Meta': Meta, 337 'formfield_callback': formfield_callback}) That's what i'm actually trying to do: # todo : get a more descriptive FC prefix than "jpic" class JpicModelFormMetaclass(ModelFormMetaclass): """ Inherit from this, then use this new keyword argument 'jpic_field_options' with a dict of dicts such as: { 'field_name_that_is_m2m': { 'queryset': aqueryset, }, 'field_name_that_is_fk': { 'queryset': anotherqueryset, }, } This solves the problem of using a queryset made in the view as choices for a M2M/FK field ... """ def __init__(self, *args, **kwargs): jpic_field_options = False if 'jpic_field_options' in kwargs.keys(): jpic_field_options = kwargs.pop('jpic_field_options') super(JpicModelFormMetaclass, self).__init__(*args, **kwargs) if not jpic_field_options: return for field, args in jpic_field_options.items(): if field not in self.fields: continue for arg, value in args.items(): setattr(self.fields[field], arg, value) class JpicModelForm(ModelForm): __metaclass__ = JpicModelFormMetaclass This is how i tryed to copy the factory method to use my metaclass: def get_form_class(self): # HACK: we should be able to construct a ModelForm without creating # and passing in a temporary inner class class Meta: pass setattr(Meta, 'model', self.model_class) setattr(Meta, 'fields', self.get_fields()) if Group.objects.get(name='Consultants') in self.request.user.groups.all(): class_name = self.model_class_name + 'ConsultantForm' else: class_name = self.model_class_name + 'ClientForm' return JpicModelFormMetaclass(class_name.encode(), (JpicModelForm,), {'Meta': Meta, 'formfield_callback': lambda f: f.formfield()}) This error is thrown: Traceback: File "/home/python/libs/django/core/handlers/base.py" in get_response 86. response = callback(request, *callback_args, **callback_kwargs) File "/home/jpic/sites/devangels/django_tickets/views.py" in root 54. return view_class().root(request, url, action, dest_class) File "/home/jpic/sites/devangels/django_tickets/views.py" in root 210. self.formobj = self.get_form() File "/home/jpic/sites/devangels/django_tickets/views.py" in get_form 97. form = form_class(instance=self.model, jpic_field_options=options) Exception Type: TypeError at /component/1/ticket/create/ Exception Value: __init__() got an unexpected keyword argument 'jpic_field_options' Please don't mind the possible problems of my 'formfield_callback' argument, i'll fix that ... I asked on IRC and failed to fix it. Any tip will be appreciated, note that my understanding of metaclasses is currently limited so that's why i tryed to "just copy and hack". There might be a better way. Regards, James. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---