Login

ForeignKey dropdown selector

Author:
rubic
Posted:
February 28, 2007
Language:
Python
Version:
Pre .96
Tags:
dynamic foreignkey dropdown choices property
Score:
4 (after 6 ratings)

Most of the time when you want a dropdown selector based on a ForeignKey, you'll want to use snippet #26

Here's an alternative approach, perhaps useful when you want to define choices once and reuse it in different views without overriding Form __init__.

 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)

More like this

  1. Modify fields created by form_for_model by grahamu 9 years, 6 months ago
  2. RelatedNullFilterSpec: django-admin custom filter all/null/not null/choices by Codeko 5 years, 10 months ago
  3. Model Choices Helper by pmclanahan 6 years, 7 months ago
  4. Choices datatype for model by menendez 8 years, 5 months ago
  5. labeled hidden input with choices by eliasfernandez 3 years, 9 months ago

Comments

dballanc (on March 2, 2007):
<p>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.</p>

#

rubic (on March 4, 2007):
<p>No, that's not correct. To illustrate the way Python properties work:</p> <pre><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> </pre>

#

robbie (on March 6, 2007):
<p>While I haven't tried with newforms, this approach certainly doesn't work with oldforms...</p> <p>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.</p>

#

rubic (on March 6, 2007):
<p>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.</p>

#

bloodpet (on July 9, 2009):
<p>Why not just create a function? Something like this:</p> <pre>def get_choices(): return [(e.id, e.description) for e in BillCode.objects.all()] </pre> <p>So instead of:</p> <pre> choices=[('','')]+Choices().choices </pre> <p>You'll only have to use:</p> <pre> choices=[('','')]+get_choices() </pre>

#

jagdeepmalhi (on January 14, 2012):
<p>Instead of:</p> <pre> choices=[('','')]+Choices().choices </pre> <p>Only use:</p> <pre> choices=get_choices() </pre> <p>Otherwise one blank option is shown in dropbox.</p>

#

Please login first before commenting.