Interessante domanda e penso che forse meriti un po 'più di attenzione nei documenti.
Ecco un esempio da a question I've just asked:
class DateSelectorWidget(widgets.MultiWidget):
def __init__(self, attrs=None, dt=None, mode=0):
if dt is not None:
self.datepos = dt
else:
self.datepos = date.today()
# bits of python to create days, months, years
# example below, the rest snipped for neatness.
years = [(year, year) for year in year_digits]
_widgets = (
widgets.Select(attrs=attrs, choices=days),
widgets.Select(attrs=attrs, choices=months),
widgets.Select(attrs=attrs, choices=years),
)
super(DateSelectorWidget, self).__init__(_widgets, attrs)
def decompress(self, value):
if value:
return [value.day, value.month, value.year]
return [None, None, None]
def format_output(self, rendered_widgets):
return u''.join(rendered_widgets)
Cos'hai ho fatto?
- sottoclasse
django.forms.widgets.MultiWidget
- Implementato un costruttore che crea diversi
widgets.WidgetName
widget in un tupla. Questo è importante perché la super classe usa l'esistenza di questa tupla per prendersi cura di diverse cose per te.
- Il mio formato di output è pass-through, ma l'idea è che è possibile aggiungere HTML personalizzato qui se desiderate
- Ho anche implementato
decompress
perché è necessario - si dovrebbe aspettare di essere passati i valori dalla banca dati in un singolo oggetto value
. decompress
interrompe questa operazione per la visualizzazione nel widget. Come e cosa fai qui dipende da te e dipende dal widget.
cose che non ho, ma potrebbe avere, sovrascritto:
render
, questo è in realtà responsabile per il rendering widget, quindi è sicuramente bisogno di chiamare il super metodo Render se sottoclasse questo. Puoi cambiare il modo in cui le cose vengono visualizzate appena prima del rendering suddividendole in sottoclassi.
Esempio, Django markitup 's rendere metodo:
def render(self, name, value, attrs=None):
html = super(MarkItUpWidget, self).render(name, value, attrs)
if self.auto_preview:
auto_preview = "$('a[title=\"Preview\"]').trigger('mouseup');"
else: auto_preview = ''
html += ('<script type="text/javascript">'
'(function($) { '
'$(document).ready(function() {'
' $("#%(id)s").markItUp(mySettings);'
' %(auto_preview)s '
'});'
'})(jQuery);'
'</script>' % {'id': attrs['id'],
'auto_preview': auto_preview })
return mark_safe(html)
value_from_datadict
- Vedere la mia domanda here. value_from_datadict estrae il valore associato a questo widget dal dizionario dei dati di tutti i dati inviati con questo modulo. Nel caso di una multiwidget che rappresenta un singolo campo, è necessario ricostruire quel valore dai tuoi subparti multipli, che è il modo in cui i dati saranno stati inviati.
_get_media
potrebbe essere utile per te se desideri recuperare i media utilizzando la rappresentazione di media di django. L'implementazione predefinita esegue il ciclo dei widget che richiedono il supporto; se la si sottoclasse e si utilizzano widget fantastici, è necessario chiamare il super; se il tuo widget ha bisogno di qualsiasi media, devi aggiungerlo usando questo.
Per esempio, widget di markitup s' django fa questo:
def _media(self):
return forms.Media(
css= {'screen': (posixpath.join(self.miu_skin, 'style.css'),
posixpath.join(self.miu_set, 'style.css'))},
js=(settings.JQUERY_URL,
absolute_url('markitup/jquery.markitup.js'),
posixpath.join(self.miu_set, 'set.js')))
media = property(_media)
Ancora una volta, è la creazione di una tupla di percorsi nella posizione corretta, proprio come il mio widget di ha creato una tupla di widget nel Metodo __init__
.
Penso che la ricopre per importanti parti della classe MultiWidget
. Quello che stai cercando di fare dipende da ciò che hai creato/dai widget che stai usando, ed è per questo che non posso entrare facilmente nei dettagli. Tuttavia, se vuoi vedere la classe base per te stesso e dare un'occhiata ai commenti, dai un'occhiata a the source.
Questa soluzione è un po 'di un hack, ma è più in linea con il modo in cui ci aspettiamo di accedere sottocampi nel modello. http://stackoverflow.com/questions/24866936/render-only-one-part-of-a-multiwidget-in-django – farthVader