ForeignKey dropdown selector

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
from django import newforms as forms
from django.db import models

################ models ####################

class BillCode(models.Model):
    description = models.CharField(maxlength=20)

class Payment(models.Model):
    billCode = models.ForeignKey(BillCode)

################# views ####################

class Choices:
    def _choices(self):
        return [(e.id, e.description) for e in BillCode.objects.all()]
    choices = property(_choices)

class PaymentForm(forms.Form):
    billCode_id = forms.ChoiceField(label="Bill Code",
        choices=[('','')]+Choices().choices)

Comments

dballanc (on March 2, 2007):

Choices seems to be calculated at the time the module is loaded, and not dynamically (that seems to be what snippet #26 is for). So if you add a new billcode to the database, the select is not updated until the server is restarted.

#

rubic (on March 4, 2007):

No, that's not correct. To illustrate the way Python properties work:

<blockquote>
    >>> from random import random
    >>> class Random:
    ...     def _random(self):
    ...         return random()
    ...     myrandom = property(_random)
    ... 
    >>> r = Random()
    >>> r.myrandom
    0.49401656652962789
    >>> r.myrandom
    0.29781862434091533
    >>> 
</blockquote>

#

robbie (on March 6, 2007):

While I haven't tried with newforms, this approach certainly doesn't work with oldforms...

I spent some time trying to setup a field that listed its 5 most common choices at the top, but it would not update to reflect new records until a forced server reload. I can't remember exactly where the problem lay, but I have a vague memory that it was related to the method currying that Django does behind the scenes when models are loaded.

#

rubic (on March 6, 2007):

robbie: I don't have any experience with oldforms, but the first line of code should make it clear that this applies to newforms, where it's been tested and used.

#

(Forgotten your password?)

You may use Markdown syntax here, but raw HTML will be removed.