2009-04-07 27 views
15

Tôi đã thêm một phương pháp 'highlight_link' đến lớp admin.py mô hình của tôi:Django Admin: Cách truy cập đối tượng yêu cầu trong admin.py, cho phương thức list_display?

class RadioGridAdmin(admin.ModelAdmin): 

    list_display = ('start_time', highlight_link) 

    def highlight_link(self): 
     return ('some custom link') 


admin.site.register(RadioGrid, RadioGridAdmin) 

Nó trả về một liên kết tùy chỉnh cho (tôi đã rời ra highlight_link.short_description cho ngắn gọn) mỗi bản ghi trở lại trong sự thay đổi danh sách. Điều đó thật tuyệt. Nhưng tôi muốn kiểm tra chuỗi truy vấn hiện tại và thay đổi liên kết tùy chỉnh dựa trên đó. Có cách nào để truy cập đối tượng Yêu cầu trong 'highlight_link' không?

+0

Tôi muốn chỉ ra vé có liên quan này: https: // đang .djangoproject.com/ticket/13659 – Paolo

Trả lời

0

Tôi đã thử các câu trả lời khác để lại ở đây và gặp phải các vấn đề đối với tôi, đã trở nên phức tạp. Tôi đã chơi xung quanh với def __call__() và đưa ra những điều sau đây. Điều này có lẽ không phải là cách đúng để làm điều này, nhưng nó hoạt động ...

lấy biến GET đây (tất cả trong RadioGridAdmin lớp như mô tả ở trên trong bài viết đầu tiên của tôi):

def __call__(self, request, url): 
    global start_date 
    start_date = request.GET['param'] 

    return super(RadioGridAdmin, self).__call__(request, url) 

và từ đó là toàn cầu, bây giờ bạn có thể truy cập nó ở đây:

def highlight_link(self): 
    # access start_date here 
+3

globals là nguy hiểm trong bối cảnh môi trường đa luồng, chẳng hạn như đang chạy trong mod_phyton trên máy chủ apache. – Ber

3

Không có cách nào trực tiếp để thực hiện việc này. Tôi thấy 2 giải pháp khả thi.

  • Sử dụng một cửa hàng địa phương thread để cùng đối tượng yêu cầu

    from django.utils._threading_local import locals 
    
    globals = locals() 
    
    class RadioGridAdmin(admin.ModelAdmin): 
        def __call__(self, request, *args, **kwargs): 
         globals['radio_grid_admin_request'] = request 
         return super(RadioGridAdmin, self).__call__(request, *args, **kwargs) 
    
        def highlight_link(self): 
         request = globals['radio_grid_admin_request'] 
         # request.GET processing 
         return ('some custom link') 
    
  • Nếu bạn đang sử dụng cài đặt Django phi ren đơn giản nó là tốt để lưu đối tượng yêu cầu giống như thuộc tính:

    class RadioGridAdmin(admin.ModelAdmin): 
        def __call__(self, request, *args, **kwargs): 
         self.request = request 
         return super(RadioGridAdmin, self).__call__(request, *args, **kwargs) 
    
        def highlight_link(self): 
         # self.request.GET processing 
         return ('some custom link') 
    
+0

Bạn không có nghĩa là "nếu bạn đang sử dụng đơn giản ** không ** - thr eaded Django cài đặt "? –

+0

Vâng, tất nhiên. Đó là lỗi đánh máy của tôi. –

+0

Tác động bằng cách sử dụng một hoặc hai trường hợp khác trong hai trường hợp này là gì? – Gelbander

15
class RadioGridAdmin(admin.ModelAdmin): 

    def highlight_link(self, obj): 
     return (self.param) 

    def changelist_view(self, request, extra_context=None): 
     self.param = request.GET['param'] 
     return super(RadioGridAdmin,self).changelist_view(request, extra_context=extra_context) 
+0

Trọng phương pháp của ModelAdmin là một cách khá gọn gàng nhưng mã có một số lỗi: "def highlight_link (tự):" nên "def highlight_link (tự, obj):" và "siêu (RadioGridAdmin, tự) .changelist_view (...) " phải có" trả lại "ở phía trước. – jnns

+6

Đây không phải là chủ đề an toàn. Một chủ đề địa phương sẽ giải quyết vấn đề này. –

+1

@CollinAnderson Tại sao nó không an toàn? Bạn có thể giải thích cho tôi không? Cảm ơn! – mozillazg

-2

có gì sai với điều này:

def highlight_link(self, request): 
    # access start_date here 
+2

Tôi không tin rằng highlight_link sẽ nhận được đối tượng yêu cầu được chuyển cho nó. –

+1

Khi một phương thức được liệt kê dưới dạng một trường, nó sẽ được gọi tự động để tạo HTML cho trường và nó được gọi với một bộ đối số nhất định, 'yêu cầu' không phải là một trong số chúng. Chỉ cần thêm nó vào chữ ký phương thức sẽ không thay đổi cách nó được gọi. – brianmearns

11

tôi SOLV e vấn đề của tôi theo cách này.

class MyClassAdmin(admin.ModelAdmin): 

    def queryset(self, request): 
     qs = super(MyClassAdmin, self).queryset(request) 
     self.request = request 
     return qs 

Bây giờ tôi có thể sử dụng self.request ở bất kỳ nơi

CẬP NHẬT

Changed in Django 1.6: The get_queryset method was previously named queryset.

class MyClassAdmin(admin.ModelAdmin): 

    def get_queryset(self, request): 
     qs = super(MyClassAdmin, self).get_queryset(request) 
     self.request = request 
     return qs 
+0

Vẫn hoạt động, nhưng 'queryset' bây giờ phải được thay thế bằng' get_queryset'. – sebhaase

+2

Vẫn hoạt động trong 1,9 nhưng 'queryset' bây giờ phải được thay thế bằng' get_queryset'. – sebhaase

+0

@sebhaase cảm ơn, tôi đã cập nhật câu trả lời của mình. –

0
import threading 

_thread_local = threading.local() 

def get_thread_local_request(): 
    return getattr(_thread_local, "request", None) 

class RadioGridAdmin(admin.ModelAdmin): 
    list_display = ('display_field', ...) 

    def display_field(self, obj): 
     # ... 
     request = get_thread_local_request() 
     # ... 
+0

hello, với django 1.9.6 'từ django.core nhập get_thread_local_request' cho' ImportError: không thể nhập tên 'get_thread_local_request''. Bất kỳ giúp đỡ? – Paolo

+0

@Paolo cập nhật câu trả lời;) – react

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