On Feb 4, 11:17 am, Marc Aymerich <glicer...@gmail.com> wrote: > Hi! > I need to create a pretty complex class at runtime. something like > this one: > > (note: "...." means that the number of attributes can be variable) > > class VirtualUserLimitForm(ModelForm): > swap_limit = forms.CharField(max_length=100, > initial=monitor1.default_limit) > memory_limit = forms.CharField(max_length=100, > initial=monitor2.default_limit) > ... > > class Meta: > model = model > > def __init__(self, *args, **kwargs): > super(VirtualUserLimitForm, self).__init__(*args, **kwargs) > if 'instance' in kwargs: > self.fields['swap_limit'].initial = > kwargs['instance'].monitoring.filter(monitor=monitor1)[0].current > self.fields['memory_limit'].initial = > kwargs['instance'].monitoring.filter(monitor=monitor2)[0].current > ... > > I can generate all the needed code as string and then use exec(), but > it seems ugly to me. I'm wondering if there is another way more > elegant to do that? metaclasses maybe? What is your recommendation?
I'd recommend against using metaclasses (in the normal way) with Django ORM, since it (and pretty much all ORMs) already makes heavy use of metaclasses, and I doubt those metaclasses were designed to share metaclassing duties. At a minimum you'd have to derive your own metaclasses from Djangos, and that's not likely to work out well at all. The right way to do this might be to reorganize your database. It seems like you have all kinds of tables with different sets of columns, and the tables themselves are dynamic? Like if you get some data somewhere and it doesn't fit into an existing schema you make a new table for it? If that's the case then you'd be better off, perhaps, to reorganize the tables into some kind of association list. Put the "relational" aspect to use. (Left as an exercise for now but if you want pointers feel free to follow up.) But maybe you have no control of the tables; you simply have a lot of them and want to cut down on repetition. Then I think a factory function that builds a dict and passes it to type() would be reasonable. See the documentation of type() for explanation of arguments. def create_user_form(name,fields,_model): class Meta: model = _model dct = { 'Meta': Meta } for field in fields: dct[field] = forms.CharField(max_length=100, > initial=monitor1.default_limit) return type(name,(ModelForm,),dct) Carl Banks -- http://mail.python.org/mailman/listinfo/python-list