Django中使用了哪些方法属性?

时间:2011-09-07 16:57:45

标签: python django function methods

documentation for ModelAdmin.list_display下,它描述了一些配置方法/功能以便在管理员列表视图中使用和显示的方法:

  • admin_order_field(描述模型中用于按方法排序的字段)
  • allow_tags(允许显示HTML而非转义)
  • short_description(设置列的标签)
  • boolean(确定是否应将字段视为显示的布尔字段)

它将它们描述为方法属性。

附录

刚刚找到了一些用于template filters的方法/函数属性:

  • is_safe,用于将模板过滤器标记为安全
  • needs_autoescape,用于处理数据的自动转移

Django(甚至是Python)中有哪些其他方法属性?或者这些是唯一的案例吗?

澄清

为了清楚起见,这就是我所说的具体内容。

在以下代码中:

class Foo(models.Model):
    name = models.CharField(max_length=100)
    color = models.CharField(max_length=100)
    age = models.PositiveIntegerField()

    def is_adult(self):
        return age > 18
    is_adult.boolean = True
    is_adult.short_description = "Over 18?"

    def colored_name(self):
        return '<span style="color: %s">%s</span>' % (self.color, self.name)
    colored_name.allow_tags = True
    colored_name.short_desciption = "Name"
    colored_name.admin_order_field = "name"

我正在谈论的方法属性包括is_adult.booleanis_adult.short_descriptioncolored_name.allow_tagscolored_name.short_descriptioncolored_name.admin_order_field

如果您需要更多详细信息,请阅读链接文档。

附录#2

PEP 232: Function Attributes部分涵盖了这一点。 PEP指向mailing list post that lists other potential use cases for function attributes

  
      
  • 我需要将Java样式类型声明与方法关联起来   在Java方法期间可以根据其类型识别它   调度。你会如何用实例做到这一点?

  •   
  • 我需要将“语法规则”与Python方法关联起来   当解析器识别语法结构时,将调用该方法   在输入数据中。

  •   
  • 我需要将IDL声明与方法相关联,以便COM   可以从源文件生成接口定义。

  •   
  • 我需要将XPath“模式字符串”与Python方法相关联   这样当树木行走者发现一个时,可以调用该方法   XML DOM中的特定模式。

  •   
  • 我需要将多种形式的文档与方法联系起来。   它们针对不同的IDE,环境或语言进行了优化。

  •   

这是an implementation that allows method attributes to be callable

from django.contrib.admin import ModelAdmin
from datetime.datetime import now

class ProfileAdmin(ModelAdmin):

    list_display = ('votes_today',)

    class VotesToday:
        def __call__(self, model_admin, obj):
            today = now().replace(hour=0, minute=0, second=0, microsecond=0)
            return obj.vote_set.filter(created__gte=today)

        @property
        def short_description(self):
            return 'Votes today (%s)' % now().strftime('%B %d')

    @property
    def votes_today(self):
        if not hasattr(self, '__votes_today'):
            self.__votes_today = self.VotesToday()
        return self.__votes_today

2 个答案:

答案 0 :(得分:5)

有趣的是你应该问一下这个问题,我对今天早些时候的django文档中对此的不同用法感到有些惊讶:

def upper_case_name(obj):
    return ("%s %s" % (obj.first_name, obj.last_name)).upper()
upper_case_name.short_description = 'Name'
# !!! another occurrence of a "method attribute," an attribute
# assigned to a function object.

class PersonAdmin(admin.ModelAdmin):
    list_display = (upper_case_name,)

所以,这实际上意味着函数定义是一种对象。更熟悉的说法可能是:

>>> def myfunc():
...   return "myvalue"

# 'myfunc' is now an object of type 'function' in the local scope. observe:

>>> type(myfunc)
<type: 'function'>

# you can, of course call __call__ on 'myfunc':
>>> myfunc()
"myvalue"
>>> myfunc.__call__()
"myvalue"

# and because 'myfunc' is also a normal object, you can define attributes on it.
myfunc.someattribute = 'somevalue'
myfunc.is_a_function = True
myfunc.takes_args = False

所以,你的问题有点与python是“对象一直向下”的想法有关,也就是说,python中的所有东西都是一个对象。

现在为什么这有用?假设您想要收集和使用您正在编写的一组函数(或方法)上的一些元数据:

from operator import attrgetter

def add(x, y):
    return x + y

def subtract(x, y):
    return x - y

def get_attribute_value(obj, attr):
    return attrgetter(attr)(obj)

add.takes_args = True
add.number_of_args = 2
add.type_of_args = [int, int]
add.uses_black_magic = False

subtract.takes_args = True
subtract.number_of_args = 2
subtract.type_of_args = [int, int]
subtract.uses_black_magic = False

get_attribute_value.takes_args = True
get_attribute_value.number_of_args = 2
get_attribute_value.type_of_args = [object, str]
get_attribute_value.uses_black_magic = True

然后,您可以以有用的方式使用这些“方法属性”:

def perform_function_checks(function_list):
    for afunc in function_list:
        if getattr(afunc, 'takes_args'):
            print "function '%s' takes args! how unusual!" % (afunc.__name__,)
        if getattr(afunc, 'number_of_args'):
            print "function '%s' takes %s args." % (afunc.__name__, afunc.number_of_args)
        if getattr(afunc, 'type_of_args'):
            print "function '%s' takes %s args: %s" (afunc.__name__, len(afunc.type_of_args), [", and ".join(str(item)) for item in afunc.type_of_args])
        if getattr(afunc, 'uses_black_magic'):
            print "oh no! function '%s' uses black magic!" % (afunc.__name__,)

perform_function_checks([add, subtract, get_attribute_value])

# prints:
# function 'add' takes args! how unusual!
# function 'add' takes 2 args.
# function 'add' takes 2 args: <type 'int'>, and <type 'int'>
# function 'subtract' takes args! how unusual!
# function 'subtract' takes 2 args.
# function 'subtract' takes 2 args: <type 'int'>, and <type 'int'>
# function 'get_attribute_value' takes args! how unusual!
# function 'get_attribute_value' takes 2 args.
# function 'get_attribute_value' takes 2 args: <type 'object'>, and <type 'str'>
# oh no! function 'get_attribute_value' uses black magic!

现在,当然,以上仅用于说明目的,如果您实际上尝试对函数和对象进行此类内省,则可能需要使用“inspect”模块,而不是添加自己的bizarro元数据:http://docs.python.org/library/inspect.html

有关此主题的更多信息,我建议这篇文章:

http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html

- 编辑:

抱歉,我没有在附录#2下解决您的“允许方法属性可调用的实现”。

你的例子在这次讨论中有一点红鲱鱼。在那里发生的是,有人正在使用@property装饰器来装饰一个方法,使其看起来像一个属性(a.k.a。'属性')。考虑这个例子:

# let's define a simple class
class Foo():
    # and a "normal" attribute
    an_attribute = 'a value'
    # now a method that we'll decorate with the @property decorator
    @property
    def what_kind(self):
        return str(self.__class__.__name__)

# now, instances of our Foo class will have the attribute '.what_kind'.

>>> bar = Foo()

# bar is now an instance of foo.

>>> bar.an_attribute
"a value"

# and finally our decorated method:

>>> bar.what_kind
"Foo"

请注意,我们不必调用上面的'what_kind'来返回值。我认为所有@property装饰器都会自动调用.__call__()

所以,该帖子的作者正在做的是让django看到你只是在类中添加一个“普通旧”属性,实际上,.short_description和.votes_today实际上是方法。 / p>

这里有关于@property装饰器/函数的更多信息(它是内置的,BTW,所以你不需要导入它): http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/

- 编辑:解决了几个标记问题和一个错字。

答案 1 :(得分:-6)

如果我正确理解这个问题,那么这个问题就非常深远了。根据您正在查看的对象,可能存在许多方法和属性。

我建议:

  • 查看source。 Django的文档是一个很好的起点,但你会发现它比公开描述的更强大。
  • 自行设置选项卡并打开Django shell。然后,您可以选中以查看可用的方法和属性。

    python manage.py shell