2011-12-18 8 views
7

mam modele skonfigurowane tak:Django filtrowania administratora listy zmian/link do innych modeli

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') 

Teraz w moim panelu administratora podczas otwierania listy zmian dla ParentModel chcę nowego pola/kolumny w list_display z linkiem do otwarcia listy zmian w ChildModel, ale z zastosowanym filtrem, aby pokazać tylko dzieci z wybranego rodzica. Teraz zdałem sobie sprawę z tego sposobu, ale myślę, że jest bardziej przejrzysty sposób to zrobić, po prostu nie wiem, jak:

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) 

Więc moje pytanie brzmi, czy to możliwe, aby osiągnąć to samo bez tego "link hacking"? Czy jest możliwe wskazanie w osobnej kolumnie w liście zmian ParentModel, czy któreś z jej dzieci ma zabawki?

Odpowiedz

2

Myślę, że twoje podejście do wyświetlania kolumny list_children jest poprawne. Nie przejmuj się "hackowaniem linków", jest w porządku.

Aby wyświetlić kolumnę, aby wskazać, czy którekolwiek z dzieci obiektu ma zabawki, po prostu zdefiniuj inną metodę na klasie ParentAdmin i dodaj ją do list_display, jak poprzednio.

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 

Ustawianie boolean=True oznacza Django uniemożliwiała „on” lub „off” ikony jak ma to miejsce w przypadku pól logicznych. Należy zauważyć, że to podejście wymaga jednego zapytania na jednego rodzica (to jest O (n)). Będziesz musiał sprawdzić, czy uzyskasz akceptowalną wydajność w produkcji.

+0

Dziękuję za odpowiedź, to bardzo mi pomogło. Jestem zaskoczony, że django nie ma bardziej eleganckiego sposobu na link do listy zmian. W każdym razie dzięki, twoja pomoc rozwiązała teraz wszystkie moje problemy. –

Powiązane problemy