2011-12-18 36 views
7

tôi có các mô hình thiết lập như thế này:Django quản trị danh sách thay đổi lọc/liên kết đến các mô hình khác

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

Bây giờ trong bảng quản trị của tôi khi tôi mở danh sách thay đổi cho ParentModel Tôi muốn có một lĩnh vực/cột mới trong list_display có liên kết để mở danh sách thay đổi của số ChildModel nhưng với bộ lọc được áp dụng để chỉ hiển thị các trẻ em từ cha mẹ đã chọn. Để bây giờ tôi nhận ra đó với phương pháp này, nhưng tôi nghĩ rằng có một cách sạch hơn để làm điều đó, tôi chỉ không biết làm thế nào:

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) 

Vì vậy, câu hỏi của tôi là, là nó có thể đạt được như vậy mà không này "liên kết hack"? Cũng có thể chỉ ra trong một cột riêng biệt trong danh sách thay đổi ParentModel, nếu có con của nó có đồ chơi không?

Trả lời

2

Tôi nghĩ cách tiếp cận của bạn để hiển thị cột list_children là chính xác. Đừng lo lắng về 'liên kết hacking', nó là tốt.

Để hiển thị cột để cho biết liệu có con nào trong đồ vật có đồ chơi hay không, chỉ cần xác định phương thức khác trên lớp ParentAdmin và thêm nó vào list_display như trước.

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 

Cài đặt boolean=True có nghĩa là Django sẽ hiển thị biểu tượng 'bật' hoặc 'tắt' như đối với trường boolean. Lưu ý rằng phương pháp này yêu cầu một truy vấn cho mỗi phụ huynh (tức là O (n)). Bạn sẽ phải kiểm tra xem liệu bạn có nhận được hiệu suất chấp nhận được trong sản xuất hay không.

+0

Cảm ơn câu trả lời của bạn, nó thực sự đã giúp tôi rất nhiều. Tôi ngạc nhiên rằng django không có một cách thanh lịch hơn cho tính năng liên kết danh sách thay đổi. Dù sao cảm ơn, giúp đỡ của bạn giải quyết ngay bây giờ tất cả các vấn đề của tôi. –

Các vấn đề liên quan