开发者

Is there any way to make Django's USStateField() to not have a pre-selected value?

I use USStateField() from Django's localflavor in one of my models:

class MyClass(models.Model):
   state  = USStateField(blank=True)

Then I made a开发者_如何学运维 form from that class:

class MyClassForm(forms.ModelForm):
    class Meta:
        model   = MyClass

When I display the form, the field "State" is a drop-down box with "Alabama" pre-selected.

Is there any way to make the drop-down box to show no pre-selected value at all?


This seems to be a known issue (though I'm not aware of a ticket - I'd double-check there's not a ticket for it, and if not, file it):

from django.contrib.localflavor.us.us_states import STATE_CHOICES
from django.contrib.localflavor.us.forms import USStateField

class YourModelForm(forms.ModelForm):
    class Meta:
        ...

    YOUR_STATE_CHOICES = list(STATE_CHOICES)
    YOUR_STATE_CHOICES.insert(0, ('', '---------'))
    state = USStateField(widget=forms.Select(
            choices=YOUR_STATE_CHOICES))

Above code from here.


I don't really like the idea of inserting ----- into the list manually. When the field is set to blank=True, the blank option should appear at the top of the picklist automatically. Plus, if your state field is on Profile and you're using django-profiles, then you end up in the position of having to modify a reusable app.

I find it easier and cleaner to just copy the STATE_CHOICES tuple from the file contrib/localflavor/us/us_states.py into the constants.py in my project, and then in models.py:

import constants
state = models.CharField(blank=True, max_length=2, choices=constants.STATE_CHOICES) 

The blank=True option then works as expected without having to monkeypatch the list.


Just reporting that this is fixed! Also note that localflavor is now a third-party package and after installing (e.g. pip install django-localflavor) it can be used like this:

from localflavor.us.us_states import STATE_CHOICES
from localflavor.us.models import USStateField


class MyClass(models.Model):
    state = USStateField(choices=STATE_CHOICES)


A simple solution:

from localflavor.us.us_states import STATE_CHOICES


STATE_CHOICES = (('', '---------'),) + STATE_CHOICES


The following hack also seems to work in both django admin and forms defined in views:

from django.contrib.localflavor.us.us_states import STATE_CHOICES
USStateField.choices = STATE_CHOICES

The thing here is that the forms.py definition in contrib/localflavor/us/forms.py has a USStateSelect widget that does define choices as STATE_CHOICES. However, the model in contrib/localflavor/us/models.py does not define these choices. This way, blank=True settings for the field do not result in a proper blank first entry in the Select, I found out looking at db/models/fields/init.py.

An alternative fix is to change contrib/localflavor/us/models.py and add a constructor like this:

class USStateField(Field): 
    def __init__(self, *args, **kwargs):
        from us_states import STATE_CHOICES
        kwargs.setdefault('max_length', 2)
        kwargs.setdefault('choices', STATE_CHOICES)
        super(USStateField, self).__init__(*args, **kwargs)
    # etc. etc.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜