Django Admin - Désactivez l'action 'Ajouter' pour un modèle spécifique

147

J'ai un site django avec beaucoup de modèles et de formulaires. J'ai de nombreux formulaires et ensembles de formulaires personnalisés et des ensembles de formulaires en ligne, ainsi que des ensembles de validation et de requêtes personnalisés. Par conséquent, l'action d'ajout de modèle dépend des formulaires qui ont besoin d'autres choses, et le 'modèle d'ajout' dans l'administrateur de django passe par un 500 à partir d'un ensemble de requêtes personnalisé.

Est-il possible de désactiver la fonctionnalité «Ajouter $ MODEL» pour certains modèles?

Je veux /admin/appname/modelname/add/donner un 404 (ou un message d'erreur «go away» approprié), je ne veux pas que le bouton «Ajouter $ MODELNAME» soit affiché /admin/appname/modelname.

L'administrateur de Django fournit un moyen de désactiver les actions d'administration (http://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/#disabling-actions) mais la seule action pour ce modèle est «delete_selected». c'est-à-dire que les actions d'administration agissent uniquement sur les modèles existants. Y a-t-il une manière django-esque de faire cela?

Rory
la source
FYI: les 'actions' dans django admin sont la liste déroulante qui s'applique dans la vue de la liste des modifications à toutes les lignes cochées de la liste.
Tim Diggins
1
Question connexe (mais différente): stackoverflow.com/questions/1721037/…
user9876

Réponses:

342

C'est facile, il suffit de surcharger la has_add_permissionméthode dans votre Adminclasse comme ceci:

class MyAdmin(admin.ModelAdmin):
     def has_add_permission(self, request, obj=None):
        return False
Frost.baka
la source
7
Cela n'a pas fonctionné pour moi. Le bouton "Ajouter un modèle" apparaît toujours sur la page de liste des modifications du modèle.
Cerin
qu'est-ce que MyAdmin ici?
user5319825
1
N'oubliez pas d'enregistrer également MyAdmin comme: admin.site.register(MyModel, MyModelAdmin)Ajouter tout dans le admin.pydossier de l'application des modèles.
djangonaut
Et c'est exactement pourquoi j'aime tant Python et Django. Facile. A très bien fonctionné. Je vous remercie!
dxhans5
2
Fonctionne avec Django 1.11. Pas besoin de objparamètre.
fjsj
9

Par défaut, syncdb crée 3 autorisations de sécurité pour chaque modèle:

  1. Créer (aka ajouter)
  2. Changement
  3. Supprimer

Si vous êtes connecté en tant qu'administrateur, vous obtenez TOUT , quoi .

Mais si vous créez un nouveau groupe d'utilisateurs appelé "Accès général" (par exemple) vous pouvez attribuer UNIQUEMENT les autorisations CHANGE et DELETE pour tous vos modèles.

Ensuite, tout utilisateur connecté qui est membre de ce groupe n'aura pas l'autorisation "Créer", rien qui lui est lié ne s'affichera à l'écran.

Richard Cooke
la source
7

Je pense que cela vous aidera .. le code ci-dessous doit être dans le fichier 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

En plus de ce qui précède, publié par

    # This will help you to disable change functionality
    def has_change_permission(self, request, obj=None):
        return False
Sandeep Prasad Kushwaha
la source
Cela fonctionne avec 2.2. et supprimera également les boutons d'ajout et de suppression pour les super-utilisateurs. Exactement ce dont j'ai besoin.
Erik Kalkoken
2

Copiez simplement le code d'une autre réponse

# 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

Dans mon cas, j'utilise en ligne

# 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

dans service = formset.form.base_fields['service'] base_fieldsest les champs définis dans le modèle

si défini dans le formulaire, utilisez:

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

voir également

CK
la source
Oui, base_fieldset declared_fieldsc'est la découverte la plus importante que j'ai tirée de cette affaire.
CK du
0

C'est une réponse trop tardive; Publiez simplement ceci comme si quelqu'un trouvait la même solution.

Dans le fichier admin.py, vous pouvez effectuer les opérations suivantes:

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)

Ici, "readonly_fields" fait la magie. Merci.

Mohammad
la source
4
Cela n'empêche pas le bouton «ajouter» d'apparaître.
Flimm
Cette solution rendra simplement les champs de titre et de poids désactivés sur le formulaire. Cela n'empêcherait pas la création d'un nouvel objet MyModelAdmin, ce que je pense que l'OP demandait.
dxhans5