Django使用哪些方法属性?

发布于 2021-01-29 15:13:34

在它的文档下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"

我谈论的方法属性是is_adult.booleanis_adult.short_descriptioncolored_name.allow_tagscolored_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
关注者
0
被浏览
44
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    有趣的是你应该问这个问题,我对今天早些时候在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!
    

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

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

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

    -编辑:

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

    您的示例在此讨论中有一些麻烦。发生的事情是,有人在使用@property装饰器来装饰一种使其看起来像属性的方法(又名“
    attribute”)。考虑以下示例:

    # 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实际上是方法。

    以下是有关@property decorator /
    function(内置的BTW,因此您无需导入)的更多信息:http : //adam.gomaa.us/blog/2008/aug/11/the-python-
    物业内置/

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



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看