我知道,如果我需要在django-admin中爲字段定製「選擇器」,我需要創建一個自定義小部件。 但是,如果小部件必須生成兩個值(例如X和Y座標),那麼如何將它們填充到模型的兩個不同字段中呢?在兩個字段中的Widget填充值
回答
Jannis Leidel在很久以前發佈了一個小部件。 據我記得,它從地圖上的座標,並通過它一個單一的領域和一些JavaScript剪切成2個領域的2個座標。
具有自定義form結合它應該工作得很好
@downvoter:請解釋你爲什麼找到這個答案向下投票值得 – vikingosegundo 2011-03-14 22:38:00
你可以看一下日期時間字段的實施,呈現在管理員2場。
去自上而下,
管理員使用
class AdminSplitDateTime(forms.SplitDateTimeWidget):
"""
A SplitDateTime Widget that has some admin-specific styling.
"""
def __init__(self, attrs=None):
widgets = [AdminDateWidget, AdminTimeWidget]
# Note that we're calling MultiWidget, not SplitDateTimeWidget, because
# we want to define widgets.
forms.MultiWidget.__init__(self, widgets, attrs)
def format_output(self, rendered_widgets):
return mark_safe(u'<p class="datetime">%s %s<br />%s %s</p>' % \
(_('Date:'), rendered_widgets[0], _('Time:'), rendered_widgets[1]))
又使用SplitDateTimeWidget
:
class SplitDateTimeWidget(MultiWidget):
"""
A Widget that splits datetime input into two <input type="text"> boxes.
"""
date_format = DateInput.format
time_format = TimeInput.format
def __init__(self, attrs=None, date_format=None, time_format=None):
if date_format:
self.date_format = date_format
if time_format:
self.time_format = time_format
widgets = (DateInput(attrs=attrs, format=self.date_format),
TimeInput(attrs=attrs, format=self.time_format))
super(SplitDateTimeWidget, self).__init__(widgets, attrs)
def decompress(self, value):
if value:
return [value.date(), value.time().replace(microsecond=0)]
return [None, None]
這反過來又擴展了django.forms.widgets
定義的MultiWidget
,你也應該擴展。它有很多有用的方法可以覆蓋。
class MultiWidget(Widget):
"""
A widget that is composed of multiple widgets.
Its render() method is different than other widgets', because it has to
figure out how to split a single value for display in multiple widgets.
The ``value`` argument can be one of two things:
* A list.
* A normal value (e.g., a string) that has been "compressed" from
a list of values.
In the second case -- i.e., if the value is NOT a list -- render() will
first "decompress" the value into a list before rendering it. It does so by
calling the decompress() method, which MultiWidget subclasses must
implement. This method takes a single "compressed" value and returns a
list.
When render() does its HTML rendering, each value in the list is rendered
with the corresponding widget -- the first value is rendered in the first
widget, the second value is rendered in the second widget, etc.
Subclasses may implement format_output(), which takes the list of rendered
widgets and returns a string of HTML that formats them any way you'd like.
You'll probably want to use this class with MultiValueField.
"""
def __init__(self, widgets, attrs=None):
self.widgets = [isinstance(w, type) and w() or w for w in widgets]
super(MultiWidget, self).__init__(attrs)
def render(self, name, value, attrs=None):
# value is a list of values, each corresponding to a widget
# in self.widgets.
if not isinstance(value, list):
value = self.decompress(value)
output = []
final_attrs = self.build_attrs(attrs)
id_ = final_attrs.get('id', None)
for i, widget in enumerate(self.widgets):
try:
widget_value = value[i]
except IndexError:
widget_value = None
if id_:
final_attrs = dict(final_attrs, id='%s_%s' % (id_, i))
output.append(widget.render(name + '_%s' % i, widget_value, final_attrs))
return mark_safe(self.format_output(output))
def id_for_label(self, id_):
# See the comment for RadioSelect.id_for_label()
if id_:
id_ += '_0'
return id_
id_for_label = classmethod(id_for_label)
def value_from_datadict(self, data, files, name):
return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
def _has_changed(self, initial, data):
if initial is None:
initial = [u'' for x in range(0, len(data))]
else:
if not isinstance(initial, list):
initial = self.decompress(initial)
for widget, initial, data in zip(self.widgets, initial, data):
if widget._has_changed(initial, data):
return True
return False
def format_output(self, rendered_widgets):
"""
Given a list of rendered widgets (as strings), returns a Unicode string
representing the HTML for the whole lot.
This hook allows you to format the HTML design of the widgets, if
needed.
"""
return u''.join(rendered_widgets)
def decompress(self, value):
"""
Returns a list of decompressed values for the given compressed value.
The given value can be assumed to be valid, but not necessarily
non-empty.
"""
raise NotImplementedError('Subclasses must implement this method.')
def _get_media(self):
"Media for a multiwidget is the combination of all media of the subwidgets"
media = Media()
for w in self.widgets:
media = media + w.media
return media
media = property(_get_media)
def __deepcopy__(self, memo):
obj = super(MultiWidget, self).__deepcopy__(memo)
obj.widgets = copy.deepcopy(self.widgets)
return obj
我沒有完成我的小部件,但從目前的進展,我認爲這是我正在尋找的解決方案。奇怪的是,我在官方的django文檔中找不到關於multiwidget的任何信息,所以如果你知道一些信息,請提供它。 – 2010-08-16 07:04:03
我發現multiwidget只是一種處理來自不同的多個小部件的方法,然後將數據綁定在單個字段中。所以它現在看起來更像是vikingosegundo提供的JS wasy是正確的一個 – 2010-08-18 08:12:59
解決了問題的相反問題,這是如何做單個字段 - >兩個小部件 – Anentropic 2011-04-21 15:14:30
可以使部件呈現兩(隱藏)HTML的輸入,他們的名字涉及到需要填補,並通過JavaScript分配必要的值給他們的模特的領域!
如果它們不是形式的一部分,這是否工作? – 2010-08-15 12:00:32
下面是一個的ModelForm的例子: http://www.adamalton.co.uk/blog/displaying-django-genericforeignkey-as-single-form-field/
一個額外的表單字段添加到窗體(您一個Widget),並排除這兩個「真實」的字段,然後重寫init和保存方法做額外的邏輯,使其工作。
而且,同樣的問題: How to get a single widget to set 2 fields in Django?
- 1. 填充字段值
- 2. 自動填充兩個many2one字段
- 3. 如何自動填充兩個字段中的日期選擇器字段值
- 4. 表單在選擇下拉值後填充兩個字段
- 5. 填充輸入字段值
- 6. 使用jQuery填充來自兩個其他字段的值的字段
- 7. 在rails 4中填充兩個字段的下拉列表ajax
- 8. Mysql根據兩個其他字段的值自動填充字段?
- 9. Oracle頂點表單乘以兩個值並填充字段
- 10. 無法填充三個生日字段組件中的兩個
- 11. 如何創建兩個字段,其中先填充哪一個會自動填充另一個字段?
- 12. 基於其他兩個字段動態填充表單字段
- 13. 填充字段
- 14. 填充字段與另一個字段的值jQuery
- 15. IE8中的字段填充
- 16. Node.js Mongoosejs填充填充的字段
- 17. 貓鼬:填充填充的字段
- 18. 在填充auto_complete字段後填充Rails表單字段
- 19. Rails的form_for不填充值的字段
- 20. 如何結合兩個data.frames,使用行值來填充匹配的字段值
- 21. JavaScript填充字段值$ _POST的NULL?
- 22. 獲取預填充字段的值
- 23. 使用多個字段值填充字段
- 24. 可能在突出顯示的輸入字段中填充了預填充值
- 25. 基於另一個字段在訪問2007中填充字段
- 26. 。其中()由填充字段
- 27. 在wpf填充字段
- 28. 只有在填充兩個字段時才啓用按鈕
- 29. 填充EditorFor字段
- 30. 預填充字段
你能解釋一下你的問題在details.Is有X&Y – ha22109 2010-08-08 22:12:08
X和Y之間的關係是從地圖座標拍攝,我想將它們存儲在單獨的領域該模型。有沒有辦法實現這個小部件,或者我必須修改模型的保存功能? – 2010-08-09 07:24:13
Similar questions:http://stackoverflow.com/questions/2856790/ http://stackoverflow.com/questions/9333406/ – Jelko 2013-08-21 14:54:34