5

Is there any easy way to do so?

Luiz C.
  • 746
  • 11
  • 22
  • Out of curiosity, what is your use case for this? – Brian Luft Mar 05 '10 at 19:37
  • I'm trying to pull the choices list from the database. I'm also using translation, and I can't tag the string for translation since they're in the database. – Luiz C. Mar 08 '10 at 14:50
  • Are these choices being exposed to users or used for internal logic only? I'm wondering if this is something that can be handled at the forms level since it is much more common to dynamically construct choices there. Changing the choices at the model level seems to defeat the purpose of setting choices on the model in the first place. Maybe this can be approached in a different manner? – Brian Luft Mar 08 '10 at 16:14

2 Answers2

2

You can set the choices attribute to any iterable: http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.Field.choices

I haven't tested this myself so I'm not sure when the choices attribute is actually evaluated, but you may be able to assign a generator function that would calculate your desired choices.

You might also investigate using the Model post_init signal: http://docs.djangoproject.com/en/1.1/ref/signals/#post-init

This will give you access to your model after Django has initialized it and so you could set the choices at that time. You'd probably want to go through the "_meta" interface like so:

instance._meta.get_field_by_name('FIELD_NAME')[0].choices = [<choices>...]
Brian Luft
  • 1,153
  • 8
  • 12
  • That almost worked. I can see the current choices, but if I try to set it to a different value, I get the error: AttributeError: can't set attribute. – Luiz C. Mar 05 '10 at 18:37
  • 1
    Poking around in the fields source, you can see that "choices" is a read-only property: http://code.djangoproject.com/browser/django/tags/releases/1.1.1/django/db/models/fields/__init__.py#L296 Try setting to "_choices" instead. This works in the shell but I won't make any guarantees about unintended consequences. – Brian Luft Mar 05 '10 at 19:26
  • Found a big problems using this method. The choices property when changed, changes the model throughout the server, which means that later requests will have the new choices value. – Luiz C. Mar 08 '10 at 14:52
  • Right - this would essentially change the model definition. Backtracking, does it work if you set _choices on the model instance itself? YourModel.yourfield._choices = [...] – Brian Luft Mar 08 '10 at 16:18
  • There are two parts to this problem: form and model level. The form level is very simple to implement and is used when displaying a view/edit page for an entry. The model level is more complex and is used only when displaying a table that lists each entry and some of its properties. That's why this solution doesn't work for this particular case. I took another approach by using a template tag that calls a class method that retrieves the correct display name. Thanks anyways. – Luiz C. Mar 08 '10 at 18:13
  • How did other people do this? I can't get it working on 1.8, so now I have changed the my model to a `CharField` and generate the choices in the form constructor instead. Problem is that migrations are genrated from my dynamic list, so I have to migrate every time it changes, which is not good. – beruic Oct 27 '15 at 16:24
1

Set the choices in __init__().

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • I'm sorry, I wasn't clear. I meant set/change the choices attribute after a model has been initialized. – Luiz C. Mar 05 '10 at 18:15