2011-12-18 3 views
7

У меня есть модели, установленные вверх, как это:Джанго фильтрация админ список изменений/ссылки на другие модели

class ParentModel(models.Model): 
    some_col = models.IntegerField() 
    some_other = models.CharField() 

class ChildModel(models.Model) 
    parent = models.ForeignKey(ParentModel, related_name='children') 

class ToyModel(models.Model) 
    child_owner = models.ForeignKey(ChildModel, related_name='toys') 

Теперь в моей панели администратора, когда я открываю список изменений для ParentModel Я хочу новое поле/столбец в list_display со ссылкой, чтобы открыть список изменений ChildModel, но с приложенным фильтром для отображения только детей из выбранного родителя. Сейчас я понял, что это с этим методом, но я думаю, что есть более чистый способ сделать это, я просто не знаю, как:

class ParentAdmin(admin.ModelAdmin) 
    list_display = ('id', 'some_col', 'some_other', 'list_children') 
    def list_children(self, obj): 
     url = urlresolvers.reverse('admin:appname_childmodel_changelist') 
     return '<a href="{0}?parent__id__exact={1}">List children</a>'.format(url, obj.id) 
    list_children.allow_tags = True 
    list_children.short_description = 'Children'   

admin.site.register(Parent, ParentAdmin) 

Так что мой вопрос, можно ли достичь того же без этого «взлом ссылок»? Также можно указать в отдельной колонке в списке переписчиков ParentModel, если у любого из его детей есть игрушки?

ответ

2

Я думаю, что ваш подход к отображению столбца list_children верен. Не беспокойтесь о «взломе ссылок», все в порядке.

Чтобы отобразить столбец, указывающий, есть ли у какого-либо из детей объекта игрушки, просто определите другой метод в классе ParentAdmin и добавьте его в list_display, как и раньше.

class ParentAdmin(admin.ModelAdmin): 
    list_display = ('id', 'some_col', 'some_other', 'list_children', 'children_has_toys') 
    ... 
    def children_has_toys(self, obj): 
     """ 
     Returns 'yes' if any of the object's children has toys, otherwise 'no' 
     """ 
     return ToyModel.objects.filter(child_owner__parent=obj).exists() 
    children_has_toys.boolean = True 

Установка boolean=True означает Django будет оказывать «на» или «выключено» иконки, как это делает для логических полей. Обратите внимание, что для этого подхода требуется один запрос на одного родителя (т. Е. O (n)). Вам нужно будет проверить, есть ли у вас приемлемая производительность в производстве.

+0

Спасибо за ваш ответ, это действительно помогло мне. Я удивлен, что у django нет более элегантного способа для ссылки на список изменений. В любом случае спасибо, ваша помощь решила теперь все мои проблемы. –