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

Jor*_*ter 17 python django methods function

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

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

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

附录

刚刚找到了一些方法/函数属性,用于模板过滤器:

  • 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"
Run Code Online (Sandbox Code Playgroud)

我谈论的方法属性是is_adult.boolean,is_adult.short_description,colored_name.allow_tags,colored_name.short_descriptioncolored_name.admin_order_field.

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

附录#2

看起来这部分涵盖在PEP 232:功能属性中.PEP指向邮件列表帖子,列出了函数属性的其他潜在用例:

  • 我需要将Java样式类型声明与方法相关联,以便在Java方法分派期间根据其类型识别它.你会如何用实例做到这一点?

  • 我需要将"语法规则"与Python方法相关联,以便在解析器识别输入数据中的语法结构时调用该方法.

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

  • 我需要将XPath"模式字符串"与Python方法相关联,以便在树步行者发现XML DOM中的特定模式时可以调用该方法.

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

这是一个允许方法属性可调用的实现:

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
Run Code Online (Sandbox Code Playgroud)

Jam*_*mes 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,)
Run Code Online (Sandbox Code Playgroud)

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

>>> 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
Run Code Online (Sandbox Code Playgroud)

所以,你的问题有点与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
Run Code Online (Sandbox Code Playgroud)

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

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!
Run Code Online (Sandbox Code Playgroud)

现在,当然,以上仅用于说明目的,如果您实际上尝试对函数和对象进行此类内省,则可能需要使用"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装饰器来装饰一个方法,使其看起来像一个属性(又名"属性").考虑这个例子:

# 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"
Run Code Online (Sandbox Code Playgroud)

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

所以,该帖子的作者正在做的是让django看到你只是在课堂上添加一个"普通旧"属性,实际上,.short_description和.votes_today实际上是方法.

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

- 编辑:修复了几个标记问题和一个错字.