Re: dynamically instantiate a model at run time
On 24 déc, 15:01, Jeff FWwrote: > I think you've got a small typo in the code there, that might be > confusing to the OP--shouldn't the get_model() call have quotes around > "tag"? Like so: > model_class = get_model("test", "tag") Nope. In the OP's code, 'tag' is a variable which contains the name of the model class. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Re: dynamically instantiate a model at run time
I think you've got a small typo in the code there, that might be confusing to the OP--shouldn't the get_model() call have quotes around "tag"? Like so: model_class = get_model("test", "tag") -Jeff On Dec 23, 5:03 pm, bruno desthuillierswrote: > On 23 déc, 20:23, "dick...@gmail.com" wrote: > > > i'm trying to do some instantiation of models, based on run time > > parameters. i'm new to django/python so not sure the term, but the > > relative java term is reflection. > > The term in Python is... well, it isn't. With a dynamic language, it's > just daily programming, you know ?-) > > (ok, nitpicking, sorry. Please don't hold it against me - or at least > read the practical solution at the bottom before). > > > > > for example, if i have a model, in my django models.py: > > > class Foo(models.Model): > > name = models.CharField(max_length=20) > > > now in some views.py code, i'm given, say some xml that defines a new > > Foo object, so i want to dynamically create a new Foo object and save > > it. bar > > > i've tried a few things below, but namely, what i'm trying to do is > > parse the xml, see that i need to create "Foo" and set it's name to > > bar: > > > tag = "Foo" > > key = "name" > > value = "bar" > > > _temp = __import__('project.test.models', globals(), locals(), > > ['Foo'], -1) > > createobj = getattr(_temp, tag) > > This returns a class object, not an instance. > > > setattr(createobj, key, value) > > This sets the "name" attribute of *class* Foo to "bar". > > > createobj.save() > > > i'm getting unbound method on save, > > Not surprinsing since you're calling it on a class object... An > unbound method (IOW: an instance method looked up on the class) takes > an instance as first param - you know, the (in)famous 'self' > argument ? > > > What is defined (using the 'def' statement) in a class statement is > _really_ a function. It only becomes a "method" (in fact just a thin > wrapper around the class, instance and function - name it, a partial > evaluation of the function) when looked up on an instance - and an > "unbound method" (same thing modulo the instance) when looked up on > the class. > > IOW and to make a long story short: > > instance.method(arg) > # is equivalent to > cls.method(instance, arg) > # which - if and only if "method" is defined in "cls" (_not_ > inherited) > # is equivalent to: > cls.__dict__['method'](instance, arg) > > If you want to learn more about it, google for python+descriptor > +protocol. It's the same thing that powers computed attributes (aka > properties), and it's something worth learning about. > > > > and tried various ways to save. > > but i'm thinking it is in the class instantiation where the problem > > is. > > Indeed. You didn't create a Foo instance. > > Ok, now for the solution(s): > > # 1/ Django's models are all loaded at startup and cached. > # To get a model by appname/model, just use: > > from db.models.loading import get_model > model_class = get_model("test", tag) > > # NB : at this point, "model_class" is what you named "createobj" > > # 2/ once you have the class, you need an instance: > > instance = model_class() > > # 3/ then you can set the attribute and save the instance: > > setattr(instance, key, value) > instance.save() > > # ALT 1 > # you can save on typing, using keyword args > # to instanciate your model: > > from db.models.loading import get_model > model_class = get_model("test", tag) > instance = model_class(**{key:value}) > instance.save() > > # ALT2 > # and save even more typing using the > # model's manager "create" method: > > from db.models.loading import get_model > model_class = get_model("test", tag) > # create and save the instance in one step > instance = model_class.objects.create(**{key:value}) > > HTH. > > Oh, and welcome onboard BTW - we all hope you'll enjoy the trip !-) --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Re: dynamically instantiate a model at run time
On 23 déc, 20:23, "dick...@gmail.com"wrote: > i'm trying to do some instantiation of models, based on run time > parameters. i'm new to django/python so not sure the term, but the > relative java term is reflection. The term in Python is... well, it isn't. With a dynamic language, it's just daily programming, you know ?-) (ok, nitpicking, sorry. Please don't hold it against me - or at least read the practical solution at the bottom before). > for example, if i have a model, in my django models.py: > > class Foo(models.Model): > name = models.CharField(max_length=20) > > now in some views.py code, i'm given, say some xml that defines a new > Foo object, so i want to dynamically create a new Foo object and save > it. bar > > i've tried a few things below, but namely, what i'm trying to do is > parse the xml, see that i need to create "Foo" and set it's name to > bar: > > tag = "Foo" > key = "name" > value = "bar" > > _temp = __import__('project.test.models', globals(), locals(), > ['Foo'], -1) > createobj = getattr(_temp, tag) This returns a class object, not an instance. > setattr(createobj, key, value) This sets the "name" attribute of *class* Foo to "bar". > createobj.save() > > i'm getting unbound method on save, Not surprinsing since you're calling it on a class object... An unbound method (IOW: an instance method looked up on the class) takes an instance as first param - you know, the (in)famous 'self' argument ? What is defined (using the 'def' statement) in a class statement is _really_ a function. It only becomes a "method" (in fact just a thin wrapper around the class, instance and function - name it, a partial evaluation of the function) when looked up on an instance - and an "unbound method" (same thing modulo the instance) when looked up on the class. IOW and to make a long story short: instance.method(arg) # is equivalent to cls.method(instance, arg) # which - if and only if "method" is defined in "cls" (_not_ inherited) # is equivalent to: cls.__dict__['method'](instance, arg) If you want to learn more about it, google for python+descriptor +protocol. It's the same thing that powers computed attributes (aka properties), and it's something worth learning about. > and tried various ways to save. > but i'm thinking it is in the class instantiation where the problem > is. Indeed. You didn't create a Foo instance. Ok, now for the solution(s): # 1/ Django's models are all loaded at startup and cached. #To get a model by appname/model, just use: from db.models.loading import get_model model_class = get_model("test", tag) # NB : at this point, "model_class" is what you named "createobj" # 2/ once you have the class, you need an instance: instance = model_class() # 3/ then you can set the attribute and save the instance: setattr(instance, key, value) instance.save() # ALT 1 # you can save on typing, using keyword args # to instanciate your model: from db.models.loading import get_model model_class = get_model("test", tag) instance = model_class(**{key:value}) instance.save() # ALT2 # and save even more typing using the # model's manager "create" method: from db.models.loading import get_model model_class = get_model("test", tag) # create and save the instance in one step instance = model_class.objects.create(**{key:value}) HTH. Oh, and welcome onboard BTW - we all hope you'll enjoy the trip !-) --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
dynamically instantiate a model at run time
i'm trying to do some instantiation of models, based on run time parameters. i'm new to django/python so not sure the term, but the relative java term is reflection. for example, if i have a model, in my django models.py: class Foo(models.Model): name = models.CharField(max_length=20) now in some views.py code, i'm given, say some xml that defines a new Foo object, so i want to dynamically create a new Foo object and save it. bar i've tried a few things below, but namely, what i'm trying to do is parse the xml, see that i need to create "Foo" and set it's name to bar: tag = "Foo" key = "name" value = "bar" _temp = __import__('project.test.models', globals(), locals(), ['Foo'], -1) createobj = getattr(_temp, tag) setattr(createobj, key, value) createobj.save() i'm getting unbound method on save, and tried various ways to save. but i'm thinking it is in the class instantiation where the problem is. thanks! --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---