2010-03-18 42 views
37

Nếu mô hình django chứa trường khóa ngoài và nếu trường đó được hiển thị trong chế độ danh sách, thì trường đó hiển thị là văn bản, thay vì hiển thị liên kết .Phím nước ngoài trong django hiển thị danh sách quản trị

Có thể tự động hiển thị tất cả các khóa nước ngoài dưới dạng liên kết thay vì văn bản phẳng không?

(tất nhiên người ta có thể làm điều đó trên một lĩnh vực theo từng lĩnh vực, nhưng là có một phương pháp chung?)

Ví dụ:

class Author(models.Model): 
    ... 

class Post(models.Model): 
    author = models.ForeignKey(Author) 

Bây giờ tôi chọn một ModelAdmin mà tác giả xuất hiện trong chế độ danh sách:

class PostAdmin(admin.ModelAdmin): 
    list_display = [..., 'author',...] 

Hiện tại ở chế độ danh sách, trường tác giả sẽ chỉ sử dụng phương pháp __unicode__ của lớp Author để hiển thị tác giả. Trên đầu trang mà tôi muốn có một liên kết trỏ đến url của tác giả tương ứng trong trang quản trị. Điều đó có thể không?

phương pháp Manual:

Vì lợi ích của sự hoàn chỉnh, tôi thêm các phương pháp thủ công. Nó sẽ có thêm một phương pháp author_link trong lớp PostAdmin:

def author_link(self, item): 
    return '<a href="../some/path/%d">%s</a>' % (item.id, unicode(item)) 
author_link.allow_tags = True 

Điều đó sẽ làm việc cho rằng lĩnh vực cụ thể nhưng đó là không những gì tôi muốn. Tôi muốn một phương pháp chung để đạt được hiệu quả tương tự. (Một trong những vấn đề là làm thế nào để tìm ra con đường tự động đến một đối tượng trong trang quản trị django.)

Trả lời

9

Tôi không nghĩ rằng có một cơ chế để làm những gì bạn muốn tự động ra khỏi hộp.

Nhưng như xa như xác định đường dẫn đến một trang admin chỉnh sửa dựa trên id của một đối tượng, tất cả bạn cần là hai mẩu thông tin:

a) self.model._meta.app_label

b) self.model._meta.module_name

Sau đó, ví dụ, để đi đến trang chỉnh sửa cho mô hình mà bạn sẽ làm gì:

'../%s_%s_change/%d' % (self.model._meta.app_label, self.model._meta.module_name, item.id) 

hãy xem django.contrib.admin.options.ModelAdmin.get_urls để xem cách họ làm điều đó.

Tôi giả sử bạn có thể gọi một tên mô hình và một id, tạo mô hình kiểu được chỉ định để lấy nhãn và tên (không cần nhấn cơ sở dữ liệu) và tạo URL ở trên.

Nhưng bạn có chắc chắn bạn không thể nhận được bằng cách sử dụng nội tuyến không? Nó sẽ làm cho một giao diện người dùng tốt hơn để có tất cả các thành phần liên quan trong một trang ...

Edit:

Inlines (liên quan đến tài liệu) cho phép một giao diện quản trị để hiển thị một mối quan hệ cha-con trong một trang thay vì phá vỡ nó thành hai.

Trong bài viết/Tác giả dụ bạn cung cấp, sử dụng inlines sẽ có nghĩa là trang để chỉnh sửa bài viết cũng sẽ hiển thị một hình thức inline cho thêm/chỉnh sửa/gỡ bỏ các tác giả. Tự nhiên hơn nhiều cho người dùng cuối.

Những gì bạn có thể làm trong xem danh sách admin của bạn là tạo ra một callable trong mô hình bài đó sẽ khiến một dấu phẩy tách ra danh sách các tác giả. Vì vậy, bạn sẽ có dạng xem danh sách Bài đăng của bạn hiển thị các Tác giả thích hợp và bạn chỉnh sửa Tác giả được liên kết với Bài đăng trực tiếp trong giao diện Quản trị bài đăng.

+0

Cảm ơn bạn đã trả lời này! Bạn có thể giải thích về việc sử dụng các nội tuyến? Điều đó sẽ giúp ích như thế nào? –

+0

@Olivier: Đã chỉnh sửa câu trả lời của tôi để chỉ cho bạn đúng hướng về nội tuyến. – cethegeek

18

tôi đang tìm kiếm một giải pháp cho cùng một vấn đề và chạy qua câu hỏi này ... kết thúc giải quyết nó bản thân mình. OP có thể không được quan tâm nữa nhưng điều này vẫn có thể hữu ích cho ai đó.

from functools import partial 
from django.forms import MediaDefiningClass 

class ModelAdminWithForeignKeyLinksMetaclass(MediaDefiningClass): 

    def __getattr__(cls, name): 

     def foreign_key_link(instance, field): 
      target = getattr(instance, field) 
      return u'<a href="../../%s/%s/%d">%s</a>' % (
       target._meta.app_label, target._meta.module_name, target.id, unicode(target)) 

     if name[:8] == 'link_to_': 
      method = partial(foreign_key_link, field=name[8:]) 
      method.__name__ = name[8:] 
      method.allow_tags = True 
      setattr(cls, name, method) 
      return getattr(cls, name) 
     raise AttributeError 

class Book(models.Model): 
    title = models.CharField() 
    author = models.ForeignKey(Author) 

class BookAdmin(admin.ModelAdmin): 
    __metaclass__ = ModelAdminWithForeignKeyLinksMetaclass 

    list_display = ('title', 'link_to_author') 

Thay thế 'một phần' bằng 'cà ri' của Django nếu không sử dụng trăn> = 2.5.

+1

Itai Tavor, cảm ơn vì câu trả lời của bạn, nó thực sự rất khó chịu, nhưng nó có thể gây ra vấn đề, chi tiết nằm trong [câu trả lời của tôi cho một câu hỏi khác] (http://stackoverflow.com/questions/6473340/link-to-foreignkey- trong-admin-nguyên nhân-attributeerror-khi-gỡ lỗi-là-sai/7192721 # 7192721). – stepank

+0

Đối với tôi, sử dụng đường dẫn tuyệt đối của %s hoạt động tốt hơn, vì liên kết sẽ chính xác khi trên trang chi tiết đối tượng, thay vì chỉ trên trang danh sách. –

+0

tham số cho phương thức ModelAdminWith ... là gì? Tôi không có biểu mẫu "MediaDefineClass"? – Timo

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