Administrador de Django: deshabilite la acción ‘Agregar’ para un modelo específico

4 minutos de lectura

Tengo un sitio de django con muchos modelos y formularios. Tengo muchos formularios y conjuntos de formularios personalizados y conjuntos de formularios en línea y validación personalizada y conjuntos de consultas personalizados. Por lo tanto, la acción de agregar modelo depende de los formularios que necesitan otras cosas, y el ‘agregar modelo’ en el administrador de django a través de un 500 de un conjunto de consultas personalizado.

¿Hay alguna forma de deshabilitar la funcionalidad ‘Agregar $MODEL’ para ciertos modelos?

Quiero /admin/appname/modelname/add/ para dar un 404 (o un mensaje de error ‘desaparecer’ adecuado), no quiero que el botón ‘Agregar $ NOMBRE DEL MODELO’ esté activado /admin/appname/modelname vista.

El administrador de Django proporciona una forma de deshabilitar las acciones de administración (http://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/#disabling-actions), sin embargo, la única acción para este modelo es ‘delete_selected’. es decir, las acciones de administración solo actúan en los modelos existentes. ¿Hay alguna forma de Django-esque para hacer esto?

  • FYI: las ‘acciones’ en django admin son el menú desplegable que se aplica en la vista de lista de cambios a cualquier fila marcada en la lista.

    – Tim Diggins

    8 de noviembre de 2011 a las 17:39


  • Pregunta relacionada (pero diferente): stackoverflow.com/questions/1721037/…

    – usuario9876

    22 de febrero de 2013 a las 18:32

avatar de usuario
Frost.baka

Es fácil, solo sobrecarga has_add_permission método en su Admin clase así:

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

  • Esto no funcionó para mí. El botón “Agregar modelo” todavía se muestra en la página de lista de cambios del modelo.

    – Cerín

    19 de julio de 2012 a las 17:27

  • ¿Qué es MyAdmin aquí?

    – usuario5319825

    15/09/2016 a las 20:31

  • No olvide registrar también MyAdmin como: admin.site.register(MyModel, MyModelAdmin) Añadir todo en el admin.py de la carpeta de aplicaciones de los modelos.

    – djangonauta

    23 de abril de 2018 a las 9:16

  • Y esto es exactamente por lo que amo tanto a Python y Django. Simple. Funcionó muy bien. ¡Gracias!

    – dxhans5

    12 de julio de 2018 a las 3:17

  • Funciona en Django 1.11. No hay necesidad de obj parámetro.

    – fjsj

    8 de enero de 2019 a las 15:12

avatar de usuario
Sandeep Prasad Kushwaha

Creo que esto te ayudará… el siguiente código debe estar en el archivo 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

Además de lo anterior publicado por

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

  • Esto funciona con 2.2. y también eliminará los botones Agregar y Eliminar para los superusuarios. Exactamente lo que necesito.

    – Erik Kalkoken

    13 de septiembre de 2019 a las 22:08

Por defecto, syncdb crea 3 permisos de seguridad para cada modelo:

  1. Crear (también conocido como agregar)
  2. Cambio
  3. Borrar

Si ha iniciado sesión como administrador, obtendrá TODO no importa qué.

Pero si creas una nueva grupo de usuario llamó “Acceso general” (por ejemplo) luego puede asignar SOLO los permisos CAMBIAR y ELIMINAR para todos sus modelos.

Entonces, cualquier usuario que haya iniciado sesión que sea miembro de ese grupo no tendrá el permiso “Crear”, no se mostrará nada relacionado con él en la pantalla.

Solo copie el código de otra respuesta

# 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

En mi caso uso en línea

# 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

en service = formset.form.base_fields['service']
base_fields son los campos definidos en el modelo

si está definido en el formulario, use:

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

ver también

Esta es una respuesta demasiado retrasada; Simplemente publicando esto como si alguien estuviera encontrando la misma solución.

En el archivo admin.py puede hacer lo siguiente:

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)

Aquí, “readonly_fields” hace la magia. Gracias.

  • Esto no impide que aparezca el botón “añadir”.

    – Flamm

    5 de junio de 2018 a las 12:36

  • Esta solución simplemente desactivará los campos de título y peso en el formulario. No evitaría la creación de un nuevo objeto MyModelAdmin, que es lo que creo que estaba pidiendo el OP.

    – dxhans5

    12 de julio de 2018 a las 3:21


  • Esto no impide que aparezca el botón “añadir”.

    – Flamm

    5 de junio de 2018 a las 12:36

  • Esta solución simplemente desactivará los campos de título y peso en el formulario. No evitaría la creación de un nuevo objeto MyModelAdmin, que es lo que creo que estaba pidiendo el OP.

    – dxhans5

    12 de julio de 2018 a las 3:21


¿Ha sido útil esta solución?