Search code examples
pythondatabasedjangodjango-modelsstoring-information

How to store python classes into a database with Django?


I have two files:

choices.py

class SomeChoice:
    name = u"lorem"

class AnotherChoice:
    name = u"ipsum"

# etc...

models.py

from django.db import models
import choices

class SomeModel(models.Model):
    CHOICES = (
        (1, choices.SomeChoice.name),
        (2, choices.AnotherChoice.name),
        # etc...
    )
    somefield = models.IntegerField('field', choices=CHOICES)

The problem: classes from choices.py need something like a primary key to be stored in my database. Here I write these keys (1, 2, ...) by hand, but this is ugly.

For instance, I don't want to do that:

class SomeChoice:
    id = 1
    name = "lorem"

class AnotherChoice:
    id = 2
    name = "lorem"

So my question is: what is the best way to store python classes into a database ?

Please excuse my ugly english. If you need more informations, just tell me. ;-)


Solution

  • You could use pickle to store instances of the classes, but then it would be uglier, and you don't need to store the classes in the database in this case, so don't (you want to avoid hitting the database as much as possible).

    To avoid repeating the IDs in two places, you could change the code to something like that:

    choices.py

    _registry = {}
    
    def register(choice_class):
        id = len(_registry) + 1
        choice_class.id = id
        _registry[id] = choice_class
    
    def as_list():
        ret = []
        for id in sorted(_registry):
            ret.append((id, _registry[id].name))
        return ret
    
    def get_choice(id):
        return _registry[id]
    
    class SomeChoice:
        name = u"lorem"
    
    class AnotherChoice:
        name = u"ipsum"
    
    register(SomeChoice)
    register(AnotherChoice)
    

    models.py

    from django.db import models
    import choices
    
    class SomeModel(models.Model):
        somefield = models.IntegerField('field', choices=choices.as_list())