custom field for callable python object like class or function

70 views
Skip to first unread message

Michael Palumbo

unread,
Aug 22, 2012, 5:58:01 PM8/22/12
to django...@googlegroups.com
Hi,

Do you know a custom field for a callable python object like a Class or a function ?

It could store it as a string in the DB: "module1.module2.class"  or   "module1.module2.function"
With that string, it could load it as a real python object when you get it from the DB.

For example, you could do something like that:

from module1.module2 import testme
mymodel.process = testme
mymodel.save() => stores the string "module1.module2.testme"

# Later...
ins = mymodel.objects.get(..)
ins.process('OK') # ins.process can be called because it has been resolved to the testme function

Thanks.

Kurtis Mullins

unread,
Aug 22, 2012, 6:15:40 PM8/22/12
to django...@googlegroups.com
It looks like you want to, basically, store a reference to a Python object in your Model. It shouldn't be too extremely difficult. I'd create a Model for this purpose though and just use extra methods to provide any functionality you need. Just as a quick prototypical example:

class ReferenceModel(Model):
    _reference = models.CharField(max_length=150)

    def get_reference(self):
        """
        Load the string from self._reference and use some sort of a process
        to dynamically load the object.
        """

    def set_reference(self, input):
        self._reference = input

    foo = property(get_reference, set_reference)

Anyways, just a guess at one of many ways to possibly accomplish this task.
        


--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/sHDfKCKGBmEJ.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

Kurtis Mullins

unread,
Aug 22, 2012, 6:16:48 PM8/22/12
to django...@googlegroups.com
Whoops,

foo = property(get_reference, set_reference)

should be

reference = property(get_reference, set_reference)

Sorry, was reading another page to make sure I have the property code right:

Michael Palumbo

unread,
Aug 22, 2012, 6:37:50 PM8/22/12
to django...@googlegroups.com
ok thanks, so you'd rather do it with a Model than a custom field.
I actually started to make a custom field but I had a few issues while displaying it in the admin so that's why I asked the question then.

Melvyn Sopacua

unread,
Aug 22, 2012, 9:27:09 PM8/22/12
to django...@googlegroups.com
On 23-8-2012 0:37, Michael Palumbo wrote:
> ok thanks, so you'd rather do it with a Model than a custom field.
> I actually started to make a custom field but I had a few issues while
> displaying it in the admin so that's why I asked the question then.

You can pickle an object and store the result in a blob-type field or
encode it and put it in a TextArea field:
<http://docs.python.org/library/pickle.html#pickle>
It's basically what the session module is doing. Perhaps look there for
inspiration:
<https://docs.djangoproject.com/en/1.4/topics/http/sessions/#technical-details>

--
Melvyn Sopacua

Michael Palumbo

unread,
Aug 23, 2012, 12:49:55 PM8/23/12
to django...@googlegroups.com
I did not know the pickle module. This is interesting. Thanks.
However, after playing with it, I am not sure it fits totally my need because I'd like humans to be able to write a string like "modulea.moduleb.MyClass" in the admin or so.

So I kept trying making a custom field (instead of a Model) by creating a custom field, formfield and widget.
The list view works well, even though it displays <class 'modulea.moduleb.MyClass'> instead of modulea.moduleb.MyClass... 
The add page works as well, I can add a model with the value "modulea.moduleb.MyClass" in the field and then it works.
BUT I have an issue with the detail page of a model.
I get a TypeError because my field has a class reference (which is callable) and the code below then instances it!

  • c:\Users\Mike\Dropbox\development\tools\virtualenvs\django-1.4\lib\site-packages\django\forms\forms.py in as_widget
    1.             else:
    2.                 attrs['id'] = self.html_initial_id
    3.         if not only_initial:
    4.             name = self.html_name
    5.         else:
    6.             name = self.html_initial_name
    1.         return widget.render(name, self.value(), attrs=attrs)
      ...
    1.     def as_text(self, attrs=None, **kwargs):
    2.         """
    3.         Returns a string of HTML for representing this as an <input type="text">.
    4.         """
    5.         return self.as_widget(TextInput(), attrs, **kwargs)
    VariableValue
    auto_id
    u'id_mapper_class'
    widget
    <xmlmapping.fieldsbis.PickleWidget object at 0x05B13290>
    name
    'mapper_class'
    self
    <django.forms.forms.BoundField object at 0x05B1A9F0>
    only_initial
    False
    attrs
    {'id': u'id_mapper_class'}
  • c:\Users\Mike\Dropbox\development\tools\virtualenvs\django-1.4\lib\site-packages\django\forms\forms.py in value
    1.         """
    2.         Returns the value for this BoundField, using the initial value if
    3.         the form is not bound or the data otherwise.
    4.         """
    5.         if not self.form.is_bound:
    6.             data = self.form.initial.get(self.name, self.field.initial)
    7.             if callable(data):
    1.                 data = data()
      ...
    1.         else:
    2.             data = self.field.bound_data(
    3.                 self.data, self.form.initial.get(self.name, self.field.initial)
    4.             )
    5.         return self.field.prepare_value(data)
    VariableValue
    self
    <django.forms.forms.BoundField object at 0x05B1A9F0>
    data
    <class 'xmlmapping.mappers.MapperWithNoLog'>

I overrided the render method of the widget but the errors comes from self.value() of the BoundField.
How can I fix that? override that?

Any other idea?

Thanks.


Michael Palumbo

unread,
Aug 23, 2012, 12:53:01 PM8/23/12
to django...@googlegroups.com
Maybe using a Model like Kurtis mentioned will be better (and easier) than making a custom field... ?
Reply all
Reply to author
Forward
0 new messages