JCB
JCB

Reputation: 1857

Django dynamic class cannot be updated

I have a set of DB tables which store customer order counts per minute per day. Each month of the year is a different table in order to avoid excessively large tables. In order to retrieve this data in my Django webpage, I dynamically create a model class with db_table being populated based on the date received from an html form input. The problem is that when I resubmit the form with a new date value, the class does not update to what should be the new model, it still maintains the old value.

My models.py looks something like this:

class baseModel(models.Model):
    id = models.CharField(max_length=40)
    date = models.IntegerField()
    minute = models.IntegerField()
    totalorders = models.IntegerField()
    class Meta:
        abstract = True
        managed = False

def getModel(type, yyyymm):
    if type == 'duration':
        class DurationClass(baseModel):
            medianduration = models.IntegerField()
            avgduration = models.IntegerField()
            class Meta:
                db_table='orderTable' + yyyymm
                #debug statement
                print db_table
        return DurationClass

yyyymm is just a string, like '201204' for April 2012. So if I enter April 2012 into the input box it works fine but then if I change to March 2012, it still queries for April data. I can see from the debug statement that db_table is being properly updated, but for some reason it's not working. Do I need to deallocate the old dynamic model before allocating a new one or something? In view.py, I'm just doing this (not in a loop):

myModel = getModel('duration', startyyyymm)
QS = myModel.objects.using( ...etc

Many thanks for any ideas.

Upvotes: 0

Views: 356

Answers (2)

Vivek S
Vivek S

Reputation: 5550

All you need is given the below link: https://code.djangoproject.com/wiki/DynamicModels

Upvotes: 1

marianobianchi
marianobianchi

Reputation: 8488

You have a problem about how python manage the creation of dynamic clases. I don't know exactly how python works, but it seems to be that the way you do it is not totally correct. I think it is because python classes are attached to one module, so the first time you execute "getModel" it creates the model as you expect. But, after that, every time you execute "getModel", as the class has always the same name, python can't create the same class at the same module, so it somehow returns you the same class you create the first time you call "getModel". (I hope you understand my English, although i might be wrong about how python dynamic classes creation works)

I search a little and make some tests before giving you an answer. It seems to be that the best way of creating a dynamic class is using "type" (python built-in method), so you can create one class per table (this classes must have a different name).

Here's an example of what you can do (it worked for me):

def getModel(type, yyyymm):
    if type == 'duration':
        newModelClass = type(
            'newModelName', #It could be the table name you are going to search in. It must be different for every different db table you want to use. For example: 'orderTable' + yyyymm
            (baseModel, ), #Base class for your new model
            {
                'medianduration' : models.IntegerField(), #New model's attribute
                'avgduration' : models.IntegerField(), #New model's attribute
                '__module__':__name__, #This is required. If not given, type raises a KeyError
                'Meta': type(
                                'Meta',
                                (object,),
                                {
                                    'db_table':'orderTable' + yyyymm, #Here you put the table name you want to use
                                    '__module__':__name__,
                                }
                        )
            }
       )
       return newModelClass

If i didn't make any copy/paste mistake, it should now work for you.

Again, sorry if i make any English mistake. I'm a little bit rusty at writing in English and in English in general :S

I hope it helps you. Althought i agree that your database should work fine without using multiple tables...

Upvotes: 3

Related Questions