Adding a attribute to a model property

42 views
Skip to first unread message

Bernd Wechner

unread,
Jun 8, 2017, 6:19:10 AM6/8/17
to Django users

I'm a tad stuck getting my head around decorating a decorator and how to do this well. But here is a proforma model:

class Thing(models.Model):
    my_field =  models.CharField('My Field')

    @property
    def my_property(self)
        .... do stuff ...
        return something

Now I am rendering on pages a number of such properties, it's lovely. All works well.

But some of these properties are expensive to evaluate, and so I would like the view to know what type the property is returning.

I'm content for now to have two types, scalar and list say and would ideally have something like this:

class Thing(models.Model):
    my_field =  models.CharField('My Field')

    @typed_property('scalar')
    def my_property(self)
        .... do stuff ...
        return something

and then be able to question this type elsewhere in the view. I am successfully finding all the properties of an object as follows (where:

    def is_property(name):
        return isinstance(getattr(self.model, name), property)

    properties = [name for name in dir(self.model) if is_property(name)]

Noting that self has a 'model' property in this context that is a model I've defined above (like Thing).

This works charmingly. Though I admit I don't fully understand it. The type "property" passed to isinstance seems to be a built in type as I don't import it anywhere and I can't find a definition (I use PyDev and it brilliantly lets me select almost anything and press F3 and takes me to its definition, but not for this 'property' keyword). And yet it's not documented here:

    https://docs.python.org/3.1/library/stdtypes.html

Now I'd like in this context to find all the scalar properties for example and skip the list properties.

I am tantalizing close it seems, but the nuance of wrapping a decorator around the property and/or cached_property decorator is escaping me.

I tried this simple test:

    def property_type(result_type):
        def decorator(func):
            func.__type = result_type
            return func
        return decorator

    class Thing(models.Model):
        my_field =  models.CharField('My Field')

        @property_type('scalar')
        @property
        def my_property(self)
            .... do stuff ...
            return something

But alas it bails with:

AttributeError: 'property' object has no attribute '__type'

Reversing the order:

    def property_type(result_type):
        def decorator(func):
            func.__type = result_type
            return func
        return decorator

    class Thing(models.Model):
        my_field =  models.CharField('My Field')

        @property
        @property_type('scalar')
        def my_property(self)
            .... do stuff ...
            return something

Doesn't bail, and seems to work (and seems at the time of decorating to add the __type attribute just fine , except I can't see the .__type attribute anywhere in my view, it seems lost, I can't find a way to, well access it, find it, test if it's actually there.

And then again in the ideal, I'd wrap the property decorator itself if I had any hints on how, rather than decorating my property twice. More like my original vision above.

Quite stuck alas. I wonder if anyone has either met with such a need before and solved it or just the basic decorator and property skills to advise?

Regards,

Bernd.

Melvyn Sopacua

unread,
Jun 8, 2017, 9:07:55 AM6/8/17
to django...@googlegroups.com

On Thursday 08 June 2017 16:18:42 Bernd Wechner wrote:

 

> This works charmingly. Though I admit I don't fully understand it. The

> type "property" passed to isinstance seems to be a built in type as I

> don't import it anywhere and I can't find a definition (I use PyDev

> and it brilliantly lets me select almost anything and press F3 and

> takes me to its definition, but not for this 'property' keyword). And

> yet it's not documented here:

>

> https://docs.python.org/3.1/library/stdtypes.html

 

Nope, because it's a built-in function.

--

Melvyn Sopacua

Bernd Wechner

unread,
Jun 8, 2017, 9:54:23 AM6/8/17
to django...@googlegroups.com
Melvyn,

Aha, thanks for the insight. Found it at last. "Property" is an amazingly difficult word to search for as it happens.

Still my problem remains. But this:

"Changed in version 3.5: The docstrings of property objects are now writeable." is hopeful. Suggesting if the docstring can be written and read it can be used to communicate as desired (metadata about the property), albeit in a sub-optimal and proxy manner I guess. I wonder if I can work out how to do that? We shall see, about to put a 3 year old to bed and may fall asleep in the process ;-).

Bernd.

Melvyn Sopacua wrote:
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/4602190.fOoObd2v9N%40devstation.
For more options, visit https://groups.google.com/d/optout.


Reply all
Reply to author
Forward
0 new messages