如何在django admin中显示布尔属性

时间:2012-10-11 14:36:11

标签: django

众所周知,通过设置boolean属性,可以轻松地在Django管理员中显示方法返回值为布尔值:

class MyModel(models.Model):
    def is_something(self):
        if self.something == 'something':
            return True
        return False
    is_something.boolean = True

如何在属性中实现相同的效果,例如以下情况?

class MyModel(models.Model):
    @property
    def is_something(self):
        if self.something == 'something':
            return True
        return False

5 个答案:

答案 0 :(得分:23)

等待更好的解决方案出现,我已经通过以下方式解决了这个问题:

class MyModel(models.Model):
    def _is_something(self):
        if self.something == 'something':
            return True
        return False
    _is_something.boolean = True
    is_something = property(_is_something)

然后我会引用_is_something子类中的ModelAdmin方法:

class MyModelAdmin(admin.ModelAdmin):
    list_display = ['_is_something']

另外is_something属性:

if my_model_instance.is_something:
    print("I'm something")

答案 1 :(得分:19)

这是我发现的最简单的方法,直接在ModelAdmin中:

class MyModelAdmin(admin.ModelAdmin):
    def is_something(self, instance):
        return instance.something == "something"
    is_something.boolean = True
    is_something.short_description = u"Is something"

    list_display = ['is_something']

答案 2 :(得分:5)

您需要为模型中的属性创建一个shadowing函数。我的意思是,您需要在ModelAdmin类中重新创建一个函数,该函数的名称与主Model中定义的属性相同。

示例:

# Model
class Product(models.Model):

    @property  # you can omit this directive
    def in_stock(self):
        # boolean check return
        return self.quantity > 0

...

# Django-modeladmin
class ProductAdmin(admin.ModelAdmin):
    list_display = ('in_stock', ...)
    def in_stock(self, instance):
        return instance.in_stock

    in_stock.boolean = True        

答案 3 :(得分:2)

您可以创建一个这样的装饰器

from six.moves import reduce

def list_property(field_name, **kwargs):
    def _from_property(obj):
        rv = reduce(getattr, field_name.split("."), obj)
        return rv() if callable(rv) else rv

    for key, value in kwargs.items():
        setattr(_from_property, key, value)
    return _from_property

这是您的模型和管理员定义:

# model

class MyModel(models.Model):
    @property
    def is_something(self):
        if self.something == 'something':
            return True
        return False


# admin

class MyModelAdmin(admin.ModelAdmin):
    list_display = [list_property("is_something", boolean=True)]

对于modeladmin中的只读字段,您可以改用以下修饰符:

def field_property(field_name, **kwargs):
    def _from_property(admin, obj=None):
        if not obj:
            return None
        rv = reduce(getattr, field_name.split("."), obj)
        return rv() if callable(rv) else rv

    for key, value in kwargs.items():
        setattr(_from_property, key, value)
    return _from_property

# admin
class MyModelAdmin(admin.ModelAdmin):
    readonly_fields = ["is_something"]

    is_something = field_property("is_something", boolean=True)

答案 4 :(得分:-1)

如果将is_something定义为属性,它将是一个不可变对象,而不是一个函数,但该对象包含对fget属性中已修饰的getter的引用。我认为Django管理界面使用该属性的getter,因此这可能有效

class MyModel(models.Model):
    @property
    def is_something(self):
        if self.something == 'something':
            return True
        return False
    is_something.fget.boolean = True