views:

45

answers:

2

Hi,

I understand that in Django, the ORM doesn't support the ENUM type in MySQL or PostgreSQL, as this was originally a MySQL extension, and not portable across other DB types. So the two options are to use a "choices" argument to your model, or using a foreign key reference.

What are the pros and cons of these approaches?

For something like gender, I assume you would use "choices", e.g.:

GENDER_CHOICES = (
    ('M', 'Male'),
    ('F', 'Female'),
)
...
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)

However, for something like state names, what are the reason for and against using a separate table, and foreign keys to that table?

state = models.ForeignKey(AustralianState)

Under what circumstances would you use one versus the other?

Cheers, Victor

+2  A: 

I would use choices where the choices wouldn't change over time. If they would, a FK with a new model would be better.

Gabi Purcaru
A: 

You should also consider foreign keys when the number of potential choices is large. That's one of the reasons to consider using FK for countries or states. Otherwise, you're effectively hard-coding a lot of data in your source code.

Jordan Reiter
Is this for performance reasons? Hmm, so for a large number of states, I suppose a FK lookup table is the way to go? And then you'd just list the states in a Django fixtures?
victorhooi
It's not so much performance reasons -- performance is probably better with tuples unless you're looking at more than a couple thousand choices -- it's mostly a maintenance issue. Actually Django has a lot of country/state fields built-in under locales, I believe. And I suppose you could create a StateField that you imported into other files. Full disclosure: I'm pretty sure the country and state fields I use in parts of my apps actually do use choices instead. But FK would also be a decent choice.
Jordan Reiter
I'd add that in this case using the country and state abbreviation as the foreign key, rather than an incrementing integer, makes a lot more sense.
Jordan Reiter