4

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. ;-)

2 Answers 2

4

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())
Sign up to request clarification or add additional context in comments.

3 Comments

This is a great idea, thank you! However there's still a problem: on your example, if (for any reason) I decide to remove register(SomeChoice), all (key,class) pairs will be changed. But I need a unique and permanent key for each class. Actually the question should be: is there any way to create a unique key (natural number, non zero) for a class ?
You could adapt the registration pattern to store the registry in a file and generate a new ID only if a class was never seen before, indexing the classes by their module name + name (and taking care of concurrency problems)... Or you could write # Don't touch! above the register() calls ;)
I'm a lazy guy, so for the moment I will use the second choice. Thank you very much for your help. :)
0

What's the value of the SomeChoice and AnotherChoice classes? Why not just store the keys and values in a dictionary (kind of link CHOICES in your SomeModel) and have one new class that just represents a choice,

class UserChoice:
    def __init__(self, id, name):
        self.id = id
        self.name = name

and then you get the same functionality of your SomeChoice and AnotherChoice, but if you add more choices, you don't need more classes. Maybe your example was just over-simplified, but I don't see the value of those classes. Sorry if I missed the point completely.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.