Django Admin - Desative a ação 'Adicionar' para um modelo específico


147

Eu tenho um site de django com muitos modelos e formulários. Eu tenho muitos formulários e conjuntos de formulários personalizados e inlineformsets e validação personalizada e conjuntos de consultas personalizados. Portanto, a ação add model depende de formulários que precisam de outras coisas, e o 'add model' no django admin passa de 500 a partir de um conjunto de consultas personalizado.

Existe alguma maneira de desativar a funcionalidade 'Adicionar $ MODELO' para determinados modelos?

Desejo /admin/appname/modelname/add/fornecer uma mensagem de erro 404 (ou uma mensagem de erro adequada 'desapareça'). Não quero que o botão 'Adicionar $ MODELNAME' esteja em /admin/appname/modelnameexibição.

O administrador do Django fornece uma maneira de desativar as ações de administrador (http://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/#disabling-actions), no entanto, a única ação para este modelo é 'delete_selected'. isto é, as ações administrativas atuam apenas nos modelos existentes. Existe alguma maneira django-esque de fazer isso?


Para sua informação: 'actions' no django admin são as opções que se aplicam na exibição de lista de alterações a quaisquer linhas verificadas na lista.
precisa

1
Pergunta relacionada (mas diferente): stackoverflow.com/questions/1721037/…
user9876

Respostas:


342

É fácil, basta sobrecarregar o has_add_permissionmétodo em sua Adminclasse da seguinte forma:

class MyAdmin(admin.ModelAdmin):
     def has_add_permission(self, request, obj=None):
        return False

7
Isto não funcionou para mim. O botão "Adicionar modelo" ainda aparece na página de lista de alterações do modelo.
Cerin

o que é o MyAdmin aqui?
user5319825

1
Não se esqueça de registrar também o MyAdmin, como: admin.site.register(MyModel, MyModelAdmin)Adicione tudo à admin.pypasta de aplicativos dos modelos.
precisa saber é o seguinte

E é exatamente por isso que eu amo tanto Python e Django. Simples. Trabalhou muito bem. Obrigado!
dxhans5

2
Trabalha no Django 1.11. Não há necessidade de objparâmetro.
fjsj

9

Por padrão, o syncdb cria 3 permissões de segurança para cada modelo:

  1. Criar (aka add)
  2. mudança
  3. Excluir

Se você está logado como administrador, você obtém TUDO não importa o quê.

Mas se você criar um novo grupo de usuários chamado "Acesso Geral" (por exemplo) , poderá atribuir SOMENTE as permissões CHANGE e DELETE para todos os seus modelos.

Então, qualquer usuário conectado que seja membro desse grupo não terá permissão "Criar", nada relacionado a ele será exibido na tela.


7

Eu acho que isso vai ajudar você .. o código abaixo deve estar no arquivo admin.py

@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    list_display = ('name', )
    list_filter = ('name', )
    search_fields = ('name', )
    list_per_page = 20

    # This will help you to disbale add functionality
    def has_add_permission(self, request):
        return False

    # This will help you to disable delete functionaliyt
    def has_delete_permission(self, request, obj=None):
        return False

Além disso, conforme publicado por

    # This will help you to disable change functionality
    def has_change_permission(self, request, obj=None):
        return False

Isso funciona com o 2.2. e também removerá os botões adicionar e remover dos superusuários. Exatamente o que eu preciso.
Erik Kalkoken 13/09/19

2

Basta copiar o código de outra resposta

# In admin
# make the related field can't be added
    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        form.base_fields['service'].widget.can_add_related = False
        return form

No meu caso, eu uso inline

# In inline formset e.g. admin.TabularInline
# disable all
    def get_formset(self, request, obj=None, **kwargs):
        formset = super().get_formset(request, obj, **kwargs)
        service = formset.form.base_fields['service']
        service.widget.can_add_related = service.widget.can_change_related = service.widget.can_delete_related = False
        return formset

in service = formset.form.base_fields['service'] base_fieldssão os campos definidos no modelo

se definido no formulário, use:

product = formset.form.declared_fields['product']

Veja também


Sim, base_fieldse declared_fieldssão as descobertas mais importantes que aprendi neste caso.
CK

0

Esta é uma resposta muito atrasada; Basta postar isso como se alguém estivesse encontrando a mesma solução.

No arquivo admin.py, você pode fazer o seguinte:

class MyModelForm(forms.ModelForm):

class Meta:
    model = MyModel
    fields = '__all__'


class MyModelAdmin(admin.ModelAdmin):
    form = QuestionTrackAdminForm
    list_display = ['title', 'weight']
    readonly_fields = ['title', 'weight']

admin.site.register(MyModel, MyModelAdmin)

Aqui, "readonly_fields" faz a mágica. Obrigado.


4
Isso não impede que o botão "adicionar" apareça.
Flimm

Essa solução simplesmente desativará os campos de título e peso no formulário. Não impediria a criação de um novo objeto MyModelAdmin, que é o que acredito que o OP estava pedindo.
dxhans5
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.