Quản trị viên Django, ẩn một mô hình


85

At the root page of the admin site where registered models appear, I want to hide several models that are registered to the Django admin.

If I directly unregister those, I am not able to add new records as the add new symbol "+" dissapears.

How can this be done ?

Câu trả lời:


123

Based on x0nix's answer I did some experiments. It seems like returning an empty dict from get_model_perms excludes the model from index.html, whilst still allowing you to edit instances directly.

class MyModelAdmin(admin.ModelAdmin):
    def get_model_perms(self, request):
        """
        Return empty perms dict thus hiding the model from admin index.
        """
        return {}

admin.site.register(MyModel, MyModelAdmin)

Agreed. Only that's a problem when I don't want to change the code. What I mean is, I have a base app that I want to keep clean from dependencies on other apps. I keep these dependencies in a derived project-specific app. Now I want the admin interface to only show the derived app, not the base app. Django requires the base app to be listed in settings/INSTALLED_APPS for the derived app to work. Obviously, the base app shouldn't show, but at the same time I don't want to keep it unmodified and reusable.See [here](Stack Exchange/questions/13923968/).
Sven

6
Một cách ngắn hơn:get_model_perms = lambda self, req: {}
Tigran Saluev,

2
Điều gì sẽ xảy ra nếu tôi muốn ẩn một biểu mẫu mô hình một userAdmin nhất định?
Alireza Sanaee

Hãy cẩn thận với giải pháp này - ngay cả khi liên kết biến mất, người dùng có thể tự chuyển đến đối tượng như thế này: / admin / main / comment / 2333 / change /
goodgrief

31

Đối với Django 1.8 trở lên

Kể từ Django 1.8, ModelAdminđã có một phương thức mới được gọi là phương thức has_module_permission()chịu trách nhiệm hiển thị một mô hình trong chỉ mục quản trị.

Để ẩn một mô hình khỏi chỉ mục quản trị, chỉ cần tạo phương thức này trong ModelAdminlớp của bạn và quay lại False. Thí dụ:

class MyModelAdmin(admin.ModelAdmin):
    ...
    def has_module_permission(self, request):
        return False

Thật không may, has_module_permissionảnh hưởng đến toàn bộ ứng dụng và không chỉ một mô hình. Vì vậy, việc thêm điều này vào một mô hình trong ứng dụng gây ra 403 Cấm trong danh sách mô hình ứng dụng (/ admin / app_label /). Xem django / Contrib / admin / sites.py .
Fabian

1
@Fabian Tôi nghĩ đó là một lỗi. Tôi đã hỏi điều này trên kênh IRC của Django và một số người ở đó đồng ý rằng hành vi này là không mong muốn.
xyres

@Fabian Giả sử trang chỉ mục quản trị vẫn liên kết đến / admin / thì có thể sửa lỗi đó bằng cách như thế return request.path!='/admin/'. Rất tiếc, điều đó làm tái hiện các mô hình đó trong danh sách mô hình ứng dụng.
ecp

Tôi đã mở một vé ở đây cho lỗi này. Điều này đã được sửa chữa ở đây . Nó sẽ được bao gồm trong bản phát hành tiếp theo, hy vọng.
xyres

Trong Django 1.11, liên kết sâu vẫn hoạt động nhưng thực thể không được liệt kê trên màn hình quản trị chính
Csaba Toth

22

Có cùng một vấn đề, đây là những gì tôi đã nghĩ ra.

Giống như trong giải pháp trước - sao chép index.html từ django sang /admin/index.html của bạn và sửa đổi nó như sau:

{% for model in app.models %}
    {% if not model.perms.list_hide %}
    <tr>
    ...
    </tr>
    {% endif %}
{% endfor %}

Và tạo lớp con ModelAdmin:

class HiddenModelAdmin(admin.ModelAdmin):
    def get_model_perms(self, *args, **kwargs):
        perms = admin.ModelAdmin.get_model_perms(self, *args, **kwargs)
        perms['list_hide'] = True
        return perms

Giờ đây, bất kỳ mô hình nào được đăng ký với lớp con HiddenModelAdmin sẽ không hiển thị trong danh sách quản trị, nhưng sẽ có sẵn thông qua biểu tượng "dấu cộng" một cách chi tiết:

class MyModelAdmin(HiddenModelAdmin):
    ...

admin.site.register(MyModel, MyModelAdmin)

1

Giải pháp xấu: ghi đè mẫu chỉ mục quản trị tức là sao chép index.html từ django vào /admin/index.html của bạn và thêm một cái gì đó như sau:

{% for for model in app.models %}
    {% ifnotequal model.name "NameOfModelToHide" %}
    ...

1

Đây là một công trình thay thế dựa trên câu trả lời của x0nix hàng đầu và chỉ khi bạn hài lòng khi ẩn các hàng bằng jquery.

Sao chép dán từ câu trả lời khác phần mà tôi đã sử dụng lại

class HiddenModelAdmin(admin.ModelAdmin):
def get_model_perms(self, *args, **kwargs):
    perms = admin.ModelAdmin.get_model_perms(self, *args, **kwargs)
    perms['list_hide'] = True
    return perms

class MyModelAdmin(HiddenModelAdmin):
...

admin.site.register(MyModel, MyModelAdmin)

Sau đó cài đặt django-jquery rồi thêm khối sau vào /admin/index.htmlmẫu của bạn :

{% extends "admin:admin/index.html" %}

{% block extrahead %}
    <script type="text/javascript" src="{{ STATIC_URL }}js/jquery.js"></script>
    {% if app_list %}
      <script type="text/javascript">
        $(function(){
          {% for app in app_list %}
            {% for model in app.models %}
                {% if model.perms.list_hide %}
                    $('div.app-{{ app.app_label }}').find('tr.model-{{ model.object_name|lower }}').hide();
                {% endif %}
            {% endfor %}
          {% endfor %}
        });
     </script>
   {% endif %}
{% endblock %}

Bạn không cần phải sao chép, dán toàn bộ mẫu, chỉ cần mở rộng nó và ghi đè extraheadkhối. Bạn sẽ cần django-apptemplates để những thứ trên hoạt động.


0

Django 1.2 có các câu lệnh if mới, nghĩa là chỉ có thể có được tính năng mong muốn bằng cách ghi đè admin / index.html

{% if model.name not in "Name of hidden model; Name of other hidden model" %}
    ...
{% endif %}

Đây là một giải pháp tồi, vì nó không quan tâm đến quản trị viên đa ngôn ngữ. Tất nhiên, bạn có thể thêm tên của các kiểu máy bằng tất cả các ngôn ngữ được hỗ trợ. Đó là một giải pháp tốt vì nó không ghi đè nhiều hơn một khía cạnh của các chức năng Django cốt lõi.

Nhưng trước khi thay đổi bất cứ điều gì, tôi nghĩ mọi người nên suy nghĩ về điều này ...

Về cơ bản, vấn đề liên quan đến việc có những mô hình mà người ta không muốn sử dụng nhiều hơn là thêm một tùy chọn vào menu thả xuống thỉnh thoảng. Nó có thể được giải quyết một cách hiệu quả bằng cách tạo một tập hợp các quyền cho những người dùng "không quá cao cấp", những người hoảng sợ khi có quá nhiều kiểu máy. Trong trường hợp cần thay đổi các mô hình cụ thể, người ta có thể chỉ cần đăng nhập bằng "tài khoản nâng cao".


0

Tôi có rất nhiều quản trị viên mô hình để đăng ký và ẩn, nếu bạn muốn có một giải pháp KHÔ hơn, điều này phù hợp với tôi (Django 1.10, Python 3.5)

# admin.py

def register_hidden_models(*model_names):
    for m in model_names:
        ma = type(
            str(m)+'Admin',
            (admin.ModelAdmin,),
            {
                'get_model_perms': lambda self, request: {}
            })
        admin.site.register(m, ma)

register_hidden_models(MyModel1, MyModel2, MyModel3)

Tôi đoán bạn có thể cuộn nó vào một lớp tiện ích nếu bạn muốn sử dụng lại nó trên các ứng dụng.


0

Kể từ Django 1.8.18 , has_module_permission()vẫn còn vấn đề. Vì vậy, trong trường hợp của chúng tôi, chúng tôi cũng sử dụng get_model_perms(). Tương tự như vậy, chúng ta cần ẩn mô hình chỉ cho người dùng cụ thể, nhưng người superuserdùng sẽ có thể truy cập mục nhập chỉ mục của nó.

class MyModelAdmin(admin.ModelAdmin):
    def get_model_perms(self, request):
        if not request.user.is_superuser:
            return {}
        return super(MyModelAdmin, self).get_model_perms(request)

admin.site.register(MyModel, MyModelAdmin)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.