2010-08-12 73 views
2

我正在使用Django ModelForm,其中我的模型包含一個BooleanField,並且與該BooleanField關聯的表單窗口小部件是一個RadioSelect窗口小部件。我希望RadioSelect小部件呈現不具有選項的選項,因此用戶必須明確地做出選擇,但如果表單驗證沒有做出選擇,則表單驗證將失敗。有沒有辦法做到這一點?使用RadioSelect窗體的Python/Django BooleanField模型默認爲空

models.py

myboolean = models.BooleanField(choices=YES_NO) 

forms.py

class myModelForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(myModelForm, self).__init__(*args, **kwargs) 
     self.fields['myboolean'].widget = forms.RadioSelect(choices=YES_NO) 

回答

6

你的代碼實際上做了你所需要的。它呈現沒有選擇選項的單選按鈕,如果沒有選擇任何選項,則會生成錯誤消息。

關於您的表單代碼的小記事。我會這樣做:

class myModelForm(forms.ModelForm): 

    myboolean = forms.BooleanField(widget=forms.RadioSelect(choices=YES_NO)) 

    class Meta: 
     model = MyModel 
+0

謝謝安德烈。在看到您的解決方案後,我重新審視了我的情況,發現我的簡單示例刪除了一條重要信息。現場的ModelField覆蓋是干擾默認值的。我從這個問題中得知RadioSelect字段似乎有default = None。我有的重寫是將默認設置爲False。 (順便說一下,我使用了__init__函數,因爲我不想超過模型設置的任何默認值,比如標籤)。 – 2010-08-13 19:54:38

+0

再次感謝您對此的幫助,對於這個不好的例子感到抱歉。我試圖將問題歸結爲核心問題,但錯過了一些信息。 – 2010-08-13 19:54:56

2

不幸的是,這是一個比HTML問題更少的Django問題。 HTML規範(RFC1866)說:

在任何時候,只有一個單選按鈕被檢查。如果一組單選按鈕中沒有一個單選按鈕指定了「CHECKED」,則用戶代理必須首先檢查該組的第一個單選按鈕。

但是,瀏覽器在歷史上忽略了這一點,並以不同的方式實現了單選按鈕。

HTML也使得這個困難,因爲「選中」的<INPUT>標籤的屬性不帶參數,所以你不能使用自定義的Django的小工具,這個屬性設置爲False或否

一個可能的解決方法是放入一個小的Javascript,作爲文檔的onLoad事件的一部分運行,該事件查找頁面上的所有單選按鈕並將'checked'屬性設置爲false(例如,使用JQuery)。

+0

我喜歡JavaScript的解決方法來擦除選中的值。我唯一的擔心是Django不會抱怨空的單選按鈕框並將它們評估爲false。我寧願它拋出驗證錯誤。 – 2010-08-12 19:21:27

+0

正如Andrey在下面提到的,如果沒有選擇單選按鈕,那麼Django應該拋出驗證錯誤,因爲'required'默認爲True。 – KeithL 2010-08-13 11:38:56

+0

很高興知道。我不確定一個BooleanField如何影響RadioSelect小部件,因爲它看起來像我發現使用IntegerField的很多示例。感謝您的輸入。 – 2010-08-13 19:57:34

0

我創建了自定義字段的默認小部件。

把我的models.py的:

class Order(models.Model): 
    ... 
    # transport = models.CharField(choices=transport.choices,max_length=25,null=True) 
    transport = SelectField(choices=transport.choices,max_length=25,null=True) 
    ... 

字段定義:

from django.db import models 
from django.forms import widgets 

class SelectField(models.CharField): 
    def formfield(self, **kwargs): 
     if self._choices: 
      defaults = {'widget': widgets.RadioSelect} 
     defaults.update(kwargs) 
     return super(SelectField, self).formfield(**defaults)