2011-12-18 9 views
7

tengo los modelos creados de esta manera:Django filtrado de administración de lista de cambios/enlace a otros modelos

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

Ahora en mi panel de administración cuando abra la lista de cambios para ParentModel Quiero un nuevo campo/columna en la list_display con un enlace para abrir la lista de cambios del ChildModel pero con un filtro aplicado para mostrar solo los elementos secundarios del padre seleccionado. Por el momento me di cuenta que con este método, pero creo que es una forma más limpia de hacerlo, simplemente no sé cómo:

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) 

Así que mi pregunta es, ¿es posible lograr lo mismo sin este "Hacking de enlaces"? También es posible indicar en una columna separada en la lista de cambios ParentModel, si alguno de sus hijos tiene juguetes?

Respuesta

2

Creo que su enfoque para mostrar la columna list_children es correcto. No te preocupes por el "pirateo de enlaces", está bien.

Para mostrar una columna para indicar si alguno de los niños del objeto tiene juguetes, simplemente definir otro método en la clase ParentAdmin, y agregarlo a list_display como antes.

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 

Configuración boolean=True significa Django hará que el 'on' u 'off' iconos como lo hace para los campos booleanos. Tenga en cuenta que este enfoque requiere una consulta por padre (es decir, O (n)). Deberá probar para ver si obtiene un rendimiento aceptable en producción.

+0

Gracias por su respuesta, de hecho me ayudó mucho. Me sorprende que django no tenga una forma más elegante para la función de enlace de lista de cambios. De todos modos, gracias, tu ayuda resolvió todos mis problemas. –

Cuestiones relacionadas