Django admin, modeli gizle


87

Kayıtlı modellerin göründüğü yönetici sitesinin kök sayfasında, Django yöneticisine kayıtlı birkaç modeli gizlemek istiyorum.

Bunların kaydını doğrudan iptal edersem, yeni "+" ekle simgesi kaybolacağından yeni kayıt ekleyemem.

Bu nasıl yapılabilir?

Yanıtlar:


124

X0nix'in cevabına dayanarak bazı deneyler yaptım. get_model_permsModeli index.html'den hariç tutarak boş bir dikte döndürmek gibi görünüyor , ancak yine de örnekleri doğrudan düzenlemenize izin veriyor.

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)

Kabul. Sadece kodu değiştirmek istemediğimde bu bir problemdir. Demek istediğim, diğer uygulamalara bağımlılıklardan arındırmak istediğim temel bir uygulamam var. Bu bağımlılıkları, projeye özgü türetilmiş bir uygulamada tutuyorum. Şimdi yönetici arayüzünün temel uygulamayı değil, yalnızca türetilen uygulamayı göstermesini istiyorum. Django, türetilmiş uygulamanın çalışması için temel uygulamanın ayarlar / INSTALLED_APPS'de listelenmesini gerektirir. Açıkçası, temel uygulama gösterilmemelidir, ancak aynı zamanda onu değiştirilmemiş ve yeniden kullanılabilir durumda tutmak istemiyorum . Bkz. [Burada] ( Stack Exchange / Questions / 13923968 /).
Sven

6
Daha kısa bir yol:get_model_perms = lambda self, req: {}
Tigran Saluev

3
Bir modeli belirli bir userAdmin'den gizlemek istersem ne olur?
Alireza Sanaee

1
Bu çözüme dikkat edin - bağlantı
kaybolsa

35

Django 1.8 ve üstü için

Django 1.8'den beri, bir modeli yönetici dizininde görüntülemekten sorumlu olan ModelAdminyeni bir yönteme sahiptir has_module_permission().

Bir modeli yönetici dizininden gizlemek için, bu yöntemi ModelAdminsınıfınızda oluşturup geri dönmeniz yeterlidir False. Misal:

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

Maalesef has_module_permissionyalnızca bir modeli değil, tüm uygulamayı etkiler. Bu nedenle, bunu uygulamadaki bir modele eklemek, uygulama modeli listesinde (/ admin / app_label /) bir 403 Yasaklanmasına neden olur. Bkz Django / contrib / yönetici / sites.py .
Fabian

1
@Fabian Bence bu bir hata. Bunu Django'nun IRC kanalında sordum ve oradaki bazı insanlar bu davranışın istenmeyen olduğu konusunda hemfikir.
xyres

@Fabian Yönetici indeks sayfasının hala / admin / bağlantısı olduğunu varsayarsak, bu hatayı gibi bir şeyle aşmak mümkündür return request.path!='/admin/'. Ne yazık ki bu, uygulama modeli listesinde bu modelleri yeniden etkinleştirir.
ecp

Bu hata için buradan bir bilet açmıştım. Bu burada düzeltildi . Umarım bir sonraki sürüme dahil edilmelidir.
xyres

Django 1.11'de derin bağlantı hala çalışıyor ancak varlık ana yönetici ekranında listelenmiyor
Csaba Toth

22

Aynı problem var, işte bulduğum şey.

Önceki çözümde olduğu gibi - index.html'yi django'dan /admin/index.html dosyanıza kopyalayın ve şu şekilde değiştirin:

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

Ve ModelAdmin alt sınıfı oluşturun:

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

Artık HiddenModelAdmin alt sınıfına kayıtlı herhangi bir model yönetici listesinde görünmeyecek, ancak "artı" simgesiyle ayrıntılı olarak kullanılabilecektir:

class MyModelAdmin(HiddenModelAdmin):
    ...

admin.site.register(MyModel, MyModelAdmin)

1

Çirkin çözüm: yönetici dizini şablonunu geçersiz kılın, yani django'daki index.html dosyasını /admin/index.html'nize kopyalayın ve buna benzer bir şey ekleyin:

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

1

Bu, x0nix'in cevabındaki alternatif bir yapıdır ve yalnızca satırları jquery ile saklamaktan memnunsanız.

Tekrar kullandığım kısmı diğer cevaptan yapıştırarak kopyala

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)

Sonra django-jquery'yi kurun ve ardından /admin/index.htmlşablonunuza aşağıdaki bloğu ekleyin :

{% 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 %}

Tüm şablonu kopyalayıp yapıştırmanıza gerek yoktur, sadece uzatın ve extraheadbloğu geçersiz kılın . Yukarıdakilerin çalışması için django-apptemplates'e ihtiyacınız olacak.


0

Django 1.2 yeni if-ifadelerine sahiptir, yani istenen özellik sadece admin / index.html üzerine yazılarak elde edilebilir.

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

Bu kötü bir çözüm çünkü çok dilli yöneticileri umursamıyor. Elbette, desteklenen tüm dillerde modellerin adlarını ekleyebilirsiniz. Bu iyi bir çözüm çünkü temel Django işlevlerinin birden fazla yönünün üzerine yazmıyor.

Ama bir şeyi değiştirmeden önce, insanların bunu düşünmesi gerektiğini düşünüyorum ...

Esasen sorun, bir kişinin arada bir açılır menüye bir seçenek eklemekten daha fazlasını kullanmak istemediği modellere sahip olmakla ilgilidir. Çok fazla model olduğunda paniğe kapılan "çok gelişmiş olmayan" kullanıcılar için bir dizi izin oluşturarak etkili bir şekilde çalışılabilir. Belirli modellerde değişiklik yapılması gerektiğinde, basitçe "gelişmiş hesap" ile oturum açılabilir.


0

Kayıt yapmam ve saklamam gereken çok sayıda model yöneticim vardı, daha kuru bir çözüm istiyorsanız, bu benim için çalıştı (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)

Sanırım, uygulamalar arasında yeniden kullanmak istiyorsanız, onu bir yardımcı program sınıfına dönüştürebilirsiniz.


0

Django 1.8.18 itibariyle , has_module_permission()hala sorun var. Yani, bizim durumumuzda biz de get_model_perms(). Aynı şekilde, modeli yalnızca belirli bir kullanıcı için gizlememiz gerekir, ancak superuserdizin girişine erişebilmeliyiz.

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.