2013-10-13 3 views
2

Я просто хочу спросить, как добавить дополнительный динамический атрибут данных html5 в каждом поле в форме администратора django.Как добавить динамический атрибут данных html5 в форме администратора django?

Например

<option value ="1" data-desc="desc1">hello1</option> 
    <option value ="2" data-desc="desc2">hello2</option> 

Спасибо,

Кель

ответ

5

Вам нужно создать подкласс ModelChoiceField Джанго и изменить его render_options() и render_option() методы, чтобы отобразить атрибуты объекта нужно. Думаю, вам также нужен ваш собственный подкласс ModelChoiceIterator, чтобы он не только выплевывал кортежи id/label, но и все данные, которые вам нужны.

Пример

Я только что нашел реализацию пользовательских SelectWidget в OpenStack's dashboard:

class SelectWidget(widgets.Select): 
    """ 
    Customizable select widget, that allows to render 
    data-xxx attributes from choices. 

    .. attribute:: data_attrs 

     Specifies object properties to serialize as 
     data-xxx attribute. If passed ('id',), 
     this will be rendered as: 
     <option data-id="123">option_value</option> 
     where 123 is the value of choice_value.id 

    .. attribute:: transform 

     A callable used to render the display value 
     from the option object. 
    """ 

    def __init__(self, attrs=None, choices=(), data_attrs=(), transform=None): 
     self.data_attrs = data_attrs 
     self.transform = transform 
     super(SelectWidget, self).__init__(attrs, choices) 

    def render_option(self, selected_choices, option_value, option_label): 
     option_value = force_unicode(option_value) 
     other_html = (option_value in selected_choices) and \ 
         u' selected="selected"' or '' 
     if not isinstance(option_label, (basestring, Promise)): 
      for data_attr in self.data_attrs: 
       data_value = html.conditional_escape(
        force_unicode(getattr(option_label, 
              data_attr, ""))) 
       other_html += ' data-%s="%s"' % (data_attr, data_value) 

      if self.transform: 
       option_label = self.transform(option_label) 
     return u'<option value="%s"%s>%s</option>' % (
      html.escape(option_value), other_html, 
      html.conditional_escape(force_unicode(option_label))) 

EDIT

До тех пор, пока вы предоставляете выбор, как это, он должен работать:

def formfield_for_foreignkey(self, db_field, request, **kwargs): 
     if db_field.name == 'dummy': 
      widget = SelectWidget(data_attrs=('bar',)) 
      choices = [(foo.id, foo) for foo in Foo.objects.all()] 
      form_field = forms.ChoiceField(
       choices=choices, widget=widget) 
      return form_field 
     return super().formfield_for_foreignkey(db_field, request, **kwargs) 
+0

Не работал для меня из коробки, используя Django 1.7, используя обычный ModelChoiceField. Мне пришлось переопределить метод label_from_instance, например: 'def label_from_instance (self, obj): return obj' – baxeico

+0

Это сложно для такой простой задачи. Джанго должен что-то сделать. –

3

Вы можете использовать метод get_form() подправить форму, которая используется в ModelAdmin.

Таким образом, вы можете изменить виджеты полей в вопросе:

class MyModelAdmin(admin.ModelAdmin): 
    def get_form(self, request, obj=None, **kwargs): 
     form = super(MyModelAdmin, self).get_form(request, obj, **kwargs) 
     form.fields['your_field'].widget.attrs.update({'data-hello': 'world'}) 
     return form 
+0

, но что, если я ant - динамический атрибут данных. как в элементе списка dropdow в admin? спасибо –

Смежные вопросы