Какие атрибуты метода используются в Django? - PullRequest
17 голосов
/ 07 сентября 2011

В документации для 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.boolean, is_adult.short_description, colored_name.allow_tags, colored_name.short_description и colored_name.admin_order_field.

Если вам нужны какие-либо подробности, пожалуйста, прочитайтесвязанная документация.

Приложение № 2

Похоже, что это частично описано в PEP 232: Атрибуты функций .PEP указывает на сообщение в списке рассылки , в котором перечислены другие возможные варианты использования атрибутов функции :

  • Мне нужно связать объявление типа в стиле Java сметод, так что он может быть распознан на основе его типа во время отправки метода Java.Как бы вы сделали это с экземплярами?

  • Мне нужно связать «правило грамматики» с методом Python, чтобы метод вызывался, когда синтаксический анализатор распознает синтаксическую конструкцию во входных данных.

  • Мне нужно связать объявление IDL с методом, чтобы можно было определить определение интерфейса COM из исходного файла.

  • Iнеобходимо связать 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

Ответы [ 2 ]

5 голосов
/ 20 сентября 2011

Забавно, что вы должны спросить об этом, я был немного удивлен другим использованием этого в документации 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. '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 decorator - это автоматически вызывает .__call__()

Итак, автор этого поста заставляет django показывать, что вы просто добавляете в класс «обычный старый» атрибут, когда на самом деле .short_description и .votes_today на самом деле являются методами.

Вот дополнительная информация о декораторе / функции @property (которая встроена в BTW, поэтому вам не нужно ее импортировать): http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/

- РЕДАКТИРОВАТЬ: исправлено несколько проблем с разметкой и опечатка.

0 голосов
/ 08 сентября 2011

Этот вопрос довольно далеко идущий, если я правильно его понимаю. В зависимости от объекта, на который вы смотрите, вероятно, существует множество методов и атрибутов.

Я рекомендую:

  • Посмотрите на источник . Документы Django являются отличной отправной точкой, но вы обнаружите, что они намного мощнее, чем то, что открыто описано.
  • Настройтесь на завершение вкладки и откройте оболочку Django. Затем вы можете просмотреть список доступных методов и атрибутов.

    python manage.py shell
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...