Question intéressante et je pense peut-être mériter un peu plus d'attention dans les docs.
Voici un exemple de 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)
Qu'as-je fait?
- subclassed
django.forms.widgets.MultiWidget
- Mis en œuvre un constructeur qui crée plusieurs
widgets.WidgetName
widgets dans un tuple . Ceci est important car la super classe utilise l'existence de ce tuple pour prendre soin de plusieurs choses pour vous.
- Ma sortie de format est traversable, mais l'idée est que vous pouvez ajouter du code HTML personnalisé ici si vous souhaitez
- J'ai aussi mis en œuvre
decompress
parce que vous devez - vous devriez vous attendre à des valeurs passées de la base de données dans un seul objet value
. decompress
rompt ceci pour l'affichage dans le widget. Comment et ce que vous faites ici est à vous et dépend du widget.
choses que j'ai pas, mais pourrait avoir, overriden:
render
, c'est en fait responsable du rendu des widgets, vous devez certainement appeler le super rendu méthode si vous sous-classe cela. Vous pouvez changer la façon dont les choses sont affichées juste avant le rendu en le sous-classant.
Exemple, django markitup « s méthode render:
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
- Voir ma question here. value_from_datadict extrait la valeur associée à ce widget du dictionnaire de données de toutes les données soumises avec ce formulaire. Dans le cas d'un multi-widget représentant un seul champ, vous devez reconstruire cette valeur à partir de vos sous-widgets multiples, ce qui correspond à la façon dont les données auront été soumises.
_get_media
peut vous être utile si vous souhaitez récupérer des médias à l'aide de la représentation django des médias. L'implémentation par défaut effectue un cycle des widgets demandant le support. si vous le sous-classez et que vous utilisez des widgets sophistiqués, vous devez appeler le super; Si votre widget nécessite un média, vous devez l'ajouter en utilisant ceci.
Par exemple, widget django de markitup Est-ce:
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)
Encore une fois, il crée un tuple de chemins vers l'emplacement correct, tout comme mon widget de a créé un tuple de widgets dans la __init__
méthode.
Je pense que cela couvre les parties importantes de la classe MultiWidget
. Ce que vous essayez de faire dépend de ce que vous avez créé/quels widgets vous utilisez, c'est pourquoi je ne peux pas entrer dans les détails facilement. Cependant, si vous voulez voir la classe de base pour vous et jeter un oeil sur les commentaires, jetez un oeil à the source.
Cette solution est un peu un hack, mais est plus en ligne avec la façon dont nous nous attendons à accéder aux sous-champs dans le modèle. http://stackoverflow.com/questions/24866936/render-only-one-part-of-a-multiwidget-in-django – farthVader