Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make the prepopulated slug field as readonly in Django Admin

I want to make the slug field as read_only depending on the other field value like "lock_slug".

Means There will be Two conditions.

1) When value of "lock_slug" is false then the slug field directly prepopulated from the field "title".

prepopulated_fields = {"slug": ("title",),}

2) When value of "lock_slug" is true then the slug field make as readonly.

def get_readonly_fields(self, request, obj = None):
    if obj and obj.lock_slug == True:
        return ('slug',) + self.readonly_fields        
    return self.readonly_fields

These two works fine independently, but problematic when used both.

Means when I try to add get_readonly_fields() on edit then it gives error because of prepopulated_fields.These two crashes with each other.

There will be any solution for working both on admin side.

I also refer below links

Making a field readonly in Django Admin, based on another field's value

django admin make a field read-only when modifying obj but required when adding new obj

But not working these two at the same time.

Thanks,

Meenakshi

like image 968
Meenakshi Avatar asked Jan 14 '23 09:01

Meenakshi


2 Answers

Here is another way:

class PostAdmin(admin.ModelAdmin):
    list_display = (
        'title',
        'slug',
    )
    prepopulated_fields = {'slug': ('title',)}

    def get_readonly_fields(self, request, obj=None):
        if obj:
            self.prepopulated_fields = {}
            return self.readonly_fields + ('slug',)
        return self.readonly_fields
like image 62
cansadadeserfeliz Avatar answered Jan 27 '23 22:01

cansadadeserfeliz


As @Rexford pointed out, the most voted answer doesn't work for recent django versions, since you can't make readonly a prepopulated field.

By the way, you can still get what you want, just override also the get_prepopulated_fields method using the same logic, i.e:

class PageAdmin(admin.ModelAdmin):
    prepopulated_fields = {
        'slug': ('title', ),
    }


    def get_readonly_fields(self, request, obj=None):
        readonly_fields = super().get_readonly_fields(request, obj)
        if request.user.is_superuser:
            return readonly_fields
        return list(readonly_fields) + ['slug', ]

    def get_prepopulated_fields(self, request, obj=None):
        prepopulated_fields = super().get_prepopulated_fields(request, obj)
        if request.user.is_superuser:
            return prepopulated_fields
        else:
            return {}
like image 38
abidibo Avatar answered Jan 27 '23 23:01

abidibo