DJango 管理员 read_only 字段

DJango admin read_only fields

下面是我的 admin.py 文件:

# readonly_fields=['product_images']
def product_images(self, obj):
    return mark_safe(
        f'''
            <img class='product' src="{obj.product_image.url}">
            <img class='product' src="{obj.product_back_image.url}">
            <img class='product' src="{obj.product_pack_image.url}">
            <img class='product' src="{obj.product_detailed_image.url}">
        '''
    )


def get_form(self, request, obj=None, **kwargs):
    # Proper kwargs are form, fields, exclude, formfield_callback
    if obj: # obj is not None, so this is a change page
        kwargs['exclude'] = ['product_image', 'product_back_image', 'product_pack_image', 'product_detailed_image']
        # self.readonly_fields=['product_images']
    else: # obj is None, so this is an add page
        kwargs['exclude'] = ['product_image_link', 'product_back_image_link', 'product_pack_image_link', 'product_detailed_image_link']
               
    return super(ProductAdmin, self).get_form(request, obj, **kwargs)

问题出在第一行,如果我取消注释它,我会得到如下错误:

是否有任何解决方法?

问题

这里的问题是 get_form 不期望 kwargs 中的 exclude。在引擎盖下,它通过将只读字段添加到 get_exclude.

的结果来创建自己的 exclude

这会被 kwargs 中的 exclude 覆盖,但是当 get_form 这样做时:

        defaults = {
            ...
            'exclude': exclude,
            ...
            **kwargs,
        }

解决方案

使用 get_exclude 挂钩而不是 get_form。它正是为这种情况而设计的。这样的事情应该可以解决问题:

class YourAdmin(admin.ModelAdmin):

    readonly_fields= ("product_images",)

    def product_images(self, obj):
        # do stuff
        return something

    def get_exclude(self, request, obj=None):
        """
        Hook for specifying exclude.
        """
        if obj: # obj is not None, so this is a change page
            return ['product_image', 'product_back_image', 'product_pack_image', 'product_detailed_image']
        else: # obj is None, so this is an add page
            return ['product_image_link', 'product_back_image_link', 'product_pack_image_link', 'product_detailed_image_link']