在Django Admin中将预填充的slug字段设为只读

5 投票
5 回答
5212 浏览
提问于 2025-04-17 13:56

我想根据另一个字段的值,比如“lock_slug”,让slug字段变成只读。

这意味着有两个条件。

1) 当“lock_slug”的值为假时,slug字段会直接从“title”字段中填充。

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

2) 当“lock_slug”的值为真时,slug字段就变成只读。

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

这两个条件各自都能正常工作,但一起用就有问题。

也就是说,当我在编辑时尝试添加get_readonly_fields()时,会因为prepopulated_fields而出错。这两个功能互相冲突。

有没有什么办法可以让这两个功能在后台同时工作呢?

我也参考了下面的链接:

根据另一个字段的值在Django后台让字段变为只读

在Django后台修改对象时让字段只读,但在添加新对象时需要该字段

但是这两个功能不能同时使用。

谢谢,

Meenakshi

5 个回答

2

正如@Rexford提到的,最受欢迎的回答在最近的django版本中不适用了,因为你不能把一个已经填充好的字段设为只读。

不过,你仍然可以实现你想要的效果,只需要重写一下get_prepopulated_fields这个方法,使用相同的逻辑,具体代码如下:

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 {}
8

这里还有另一种方法:

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
0

我们不能把预先填好的字段设置为只读。所以我创建了一个新的字段,这个字段没有预先填好,然后在这个字段上进行操作,这样我的问题就解决了。

撰写回答