2010-10-21 1 views
2

У меня есть модель bugs, которая сопоставлена ​​с categories. Категории могут владеть другими категориями.Как я могу создать пользовательское вложенное представление дерева меток в Django-admin?

class Bug(models.Model): 
    categories = models.ManyToManyField('Category') 
    name = models.CharField(max_length=100) 
    slug = models.SlugField(unique=True) 
    summary = models.TextField() 
    summary_markdown = models.TextField(editable=False, blank=True) 
    date_added = models.DateTimeField(auto_now_add=True) 
    browser = models.ManyToManyField(Browser) 
    poster = models.ForeignKey(User) 

class Category (models.Model): 
    name = models.CharField(max_length=100) 
    slug = models.SlugField(unique=True) 
    parent = models.ForeignKey('self', null=True, blank=True, related_name='children') 

    class Meta: 
    ordering = ['name'] 
    verbose_name_plural = 'Categories' 

    def __unicode__(self): 
    return self.name 

Я уже использую django-mptt на лицевой стороне для рендеринга категорий. Мне интересно, как я могу изменить представление администратора, чтобы при создании новой ошибки вместо выпадающего списка категорий в иерархическом порядке я получил иерархический порядок с флажками вместо выпадающего списка.

Что-то вроде:

(checkbox) CSS 
    (checkbox) Display 
     (checkbox) Inline-block 
     (checkbox) Block 
    (checkbox) Float 
    (checkbox) Height 
     (checkbox) Min-height 

ответ

1

У меня была аналогичная проблема, но используется макет немножко diffrent. Вам нужно создать собственный виджет для отображения категорий. Это, как я сделал это мое:

from itertools import chain 

from django import forms 
from django.db import models 
from django.forms.widgets import CheckboxSelectMultiple 
from django.utils.encoding import force_unicode 
from django.utils.html import conditional_escape 
from django.utils.safestring import mark_safe 

class CustomCheckboxSelectMultiple(forms.CheckboxSelectMultiple): 

    items_per_row = 1 # Number of items per row  

    def render(self, name, value, attrs=None, choices=()): 
     if value is None: value = [] 
     has_id = attrs and 'id' in attrs 
     final_attrs = self.build_attrs(attrs, name=name) 
     output = ['<table><tr>'] 
     # Normalize to strings 
     str_values = set([force_unicode(v) for v in value]) 
     for i, (option_value, option_label) in enumerate(chain(self.choices, choices)): 
      # If an ID attribute was given, add a numeric index as a suffix, 
      # so that the checkboxes don't all have the same ID attribute. 
      if has_id: 
       final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i)) 
       label_for = ' for="%s"' % final_attrs['id'] 
      else: 
       label_for = ''   
       cb = forms.CheckboxInput(final_attrs, check_test=lambda value: value in str_values) 
       option_value = force_unicode(option_value) 
       rendered_cb = cb.render(name, option_value) 
       option_label = conditional_escape(force_unicode(option_label)) 
       if i != 0 and i % self.items_per_row == 0: 
        output.append('</tr><tr>') 
       #Here you need to put you layout logic for display the checkboxes 
       if self.choices[i][1].parent_id is None: 
        output.append('<td nowrap><label%s>%s</label></td>' % (label_for, option_label)) 
       else: 
        output.append('<td nowrap><label%s>%s %s</label></td>' % (label_for, rendered_cb, option_label)) 

     output.append('</tr></table>')  
     return mark_safe('\n'.join(output)) 

В models.py у меня есть:

class MyModelForm(ModelForm): 
    my_model_types = forms.MultipleChoiceField(label='My model types', widget = CustomCheckboxSelectMultiple, required=True) 

    class Meta: 
     model = MyModel      

    def __init__(self, *args, **kwargs): 
     super(self.__class__, self).__init__(*args, **kwargs) 
     tree = Tree() 
     tree.build_tree(reasons=MyModelType.objects.all()) 
     list = tree.as_list()  
     CHOICES = [(rt.pk, rt) for rt in list]    
     self.fields['reason_types'].choices = CHOICES 
+0

Интересно. Где вы действительно храните этот код? 'Models.py'? Или это не имеет значения? И есть ли еще больше (называя это в другом файле)? –

+0

У меня был отдельный файл widgets.py, в котором содержался виджет – Seitaridis

+0

Я не использовал mptt для хранения отношений дерева. Дерево-класс используется для анализа данных из базы данных и создания дерева. Затем дерево было преобразовано в список для отображения – Seitaridis

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