众所周知,通过设置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
答案 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