ChatGPT解决这个技术问题 Extra ChatGPT

Django Admin - Disable the 'Add' action for a specific model

I have a django site with lots of models and forms. I have many custom forms and formsets and inlineformsets and custom validation and custom querysets. Hence the add model action depends on forms that need other things, and the 'add model' in the django admin throughs a 500 from a custom queryset.

Is there anyway to disable the 'Add $MODEL' functionality for a certain models?

I want /admin/appname/modelname/add/ to give a 404 (or suitable 'go away' error message), I don't want the 'Add $MODELNAME' button to be on /admin/appname/modelname view.

Django admin provides a way to disable admin actions (http://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/#disabling-actions) however the only action for this model is 'delete_selected'. i.e. the admin actions only act on existing models. Is there some django-esque way to do this?

FYI: 'actions' in django admin are the drop down that applies in the changelist view to any checked rows in the list.
Related (but different) question: stackoverflow.com/questions/1721037/…

D
Dadep

It is easy, just overload has_add_permission method in your Admin class like so:

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

This did not work for me. The "Add model" button still shows on the model's changelist page.
what is MyAdmin here?
Don't forget to also register MyAdmin like: admin.site.register(MyModel, MyModelAdmin) Add all into the admin.py of the models`s app folder.
And this is exactly why I love Python & Django so much. Simple. Worked great. Thank you!
Works at Django 1.11. No need for obj parameter.
A
Ajibola L'Don Jibson Olayanju

I think this will help you.. below code must be in admin.py file

@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

In additon to the above as posted by

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

This works with 2.2. and will also remove the add and remove buttons for superusers. Exactly what I need.
R
Richard Cooke

By default syncdb creates 3 security permissions for each model:

Create (aka add) Change Delete

If your logged in as Admin, you get EVERYTHING no matter what.

But if you create a new user group called "General Access" (for example) then you can assign ONLY the CHANGE and DELETE permissions for all of your models.

Then any logged in user that is a member of that group will not have "Create" permission, nothing related to it will show on the screen.


C
C.K.

Just copy code from another answer

# 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

In my case I use 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_fields is the fields defined in model

if defined in the form use:

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

see also


Yes, base_fields and declared_fields are the most important finding I learned from this case.
M
Mohammad

This is a too much delayed answer; Just posting this as if anyone is finding the same solution.

In admin.py file you can do the following:

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)

Here, "readonly_fields" does the magic. Thanks.


This doesn't prevent the "add" button from appearing.
This solution will simply make the title and weight fields disabled on the form. It wouldn't prevent the creation of a new MyModelAdmin object, which is what I believe the OP was asking for.