Interessante Frage und ich denke, vielleicht verdient ein wenig mehr Aufmerksamkeit in der Dokumentation.
Hier ist ein Beispiel von 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)
Was habe ich getan?
- subclassed
django.forms.widgets.MultiWidget
- einen Konstruktor implementiert, die mehrere
widgets.WidgetName
Widgets in einem Tupel erzeugt. Das ist wichtig, weil die Superklasse die Existenz dieses Tupels benutzt, um sich um mehrere Dinge zu kümmern.
- Mein Format ausgegeben Pass-Through, aber die Idee ist, dass Sie eigenen HTML hinzufügen können hier sollten Sie
- Ich möchte auch
decompress
implementiert haben, weil Sie zu haben - Sie sollten Werte aus der Datenbank erwarten weitergegeben in einem einzigen value
Objekt. decompress
bricht dies für die Anzeige im Widget auf. Wie und was Sie hier machen, hängt von Ihnen ab und hängt vom Widget ab.
Dinge, die ich nicht haben, konnte aber haben, außer Kraft gesetzt:
render
, ist dies tatsächlich verantwortlich für Widgets machen, so müssen Sie auf jeden Fall die Super-Render-Methode aufrufen, wenn Sie diese Unterklasse. Sie können ändern, wie die Objekte unmittelbar vor dem Rendern angezeigt werden, indem Sie diese untergliedern.
Beispiel, django markitup ‚s Methode machen:
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
- Siehe meine Frage here. value_from_datadict zieht den mit diesem Widget verknüpften Wert aus dem Datenverzeichnis aller übermittelten Daten mit diesem Formular. Im Falle eines Multiwidgets, das ein einzelnes Feld repräsentiert, müssen Sie diesen Wert aus Ihren mehreren Sub-Widgets rekonstruieren, so wie die Daten übermittelt wurden.
_get_media
kann für Sie nützlich sein, wenn Sie Medien mit Djangos Darstellung von Medien abrufen möchten. Die Standardimplementierung zykliert die Widgets, die nach dem Medium fragen; Wenn Sie es ableiten und irgendwelche ausgefallenen Widgets verwenden, müssen Sie den Super aufrufen. Wenn Ihr Widget Medien benötigt, müssen Sie es mit diesem hinzufügen.
Zum Beispiel markitup ‚s django Widget tut dies:
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)
Auch hier ist ein Tupel von Pfaden an die richtige Stelle zu schaffen, so wie mein Widget ein Tupel von Widgets in der erstellt wurde __init__
Methode.
Ich denke, dass es für wichtige Teile der MultiWidget
Klasse abdeckt. Was Sie zu tun versuchen, hängt davon ab, was Sie erstellt haben und welche Widgets Sie verwenden, weshalb ich nicht einfach auf Details eingehen kann. Wenn Sie jedoch die Basisklasse selbst sehen und sich die Kommentare ansehen möchten, werfen Sie einen Blick auf the source.
Diese Lösung ist ein bisschen wie ein Hack, ist aber mehr mit der Art und Weise, wie wir auf Unterfelder in der Vorlage zugreifen, zu erwarten. http://stackoverflow.com/questions/24866936/render-only-one-part-of-a-multiwidget-in-django – farthVader